We use a combination of the Expire and Purge modules to decide which pages are purged from the cache and to issue the command to Varnish over HTTP. We are not using the Varnish module any more although it might be better if we did; see the Important Note section.
By default, the Drupal page cache is completely cleared on a
node_save(). The Expire module allows us to have fine grained control over which pages are flushed from the cache. When a node is saved, only a few relevant items are selected to be flushed from the cache.
It's worth noting that if a node is updated, views that use that node are not. If this is required, either alter the VCL to not cache certain pages (not recommended) or find a module that expires a view page from the cache when relevant content is updated. If nothing exists, write a nodeapi hook that uses the purge module purge_urls() function. I've not looked into it but the views_content_cache module might be a good place to start.
Once pages are queued for flushing the purge module issues an HTTP request with a PURGE header to Varnish which is processed by the VCL template.
Differences between Purge and Varnish modules
Communicates with Varnish over the administration socket.Communicates via an HTTP request with a special headerRequires Drupal configuration so that the secret key variable matches the content of a secret key file on the filesystemRequires more code in the VCL file to handle PURGE requests
We're using Purge as it seemed to work better during testing. Don't run Purge and Varnish at the same time.
Whilst Purge performed perfectly on the development server, I've noticed that on the live server it seems to work but not report correctly in the syslog. Testing would indicate that it is purging URLs but the log shows an empty array and a PHP Warning due to a foreachrunning on a non-collection (most likely purge_issue_requests_curl returning FALSE).
An issue in the Purge project queue would seem to indicate that a change in the PHP implementation of curl_multi_select might be to blame. As far as I can tell, this is only breaking the reporting, not the functionality. It seems to be dependent on the PHP version. My development server is running PHP 5.3.10 and the production environment is PHP 5.3.23.
I've stuck with Purge despite this as when testing with Varnish and Expire it doesn't appear to successfully purge anything from the cache. It should work so it's possible I was just missing some configuration somewhere along the line.