Add sharded DNS publishing capability

This enables sharded DNS publishing on a per-TLD basis. Instead of a TLD-wide lock, the sharded scheme locks each update on the shard number, allowing parallel writes to DNS.

We allow N (the number of shards) to be 0 or 1 for no sharding, and N > 1 for an N-way sharding scheme. Unless explicitly set, all TLDs default to a numShards of 0, so we don't have to reload all registry objects explicitly.

WARNING: This will change the lock name upon deployment for the PublishDnsAction from "<TLD> Dns Updates" to "<TLD> Dns Updates shard 0". This may cause concurrency issues if the underlying DNSWriter is not parallel-write tolerant (currently all production usages are ZonemanWriter, which is parallel-tolerant, so no issues are expected).

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187525655
This commit is contained in:
larryruili 2018-03-01 13:33:46 -08:00 committed by jianglai
parent 24799b394d
commit fa989e754b
16 changed files with 474 additions and 64 deletions

View file

@ -19,15 +19,20 @@ import static google.registry.dns.DnsConstants.DNS_PULL_QUEUE_NAME;
import static google.registry.dns.PublishDnsUpdatesAction.PARAM_DNS_WRITER;
import static google.registry.dns.PublishDnsUpdatesAction.PARAM_DOMAINS;
import static google.registry.dns.PublishDnsUpdatesAction.PARAM_HOSTS;
import static google.registry.dns.PublishDnsUpdatesAction.PARAM_LOCK_INDEX;
import static google.registry.dns.PublishDnsUpdatesAction.PARAM_NUM_PUBLISH_LOCKS;
import static google.registry.dns.PublishDnsUpdatesAction.PARAM_PUBLISH_TASK_ENQUEUED;
import static google.registry.dns.PublishDnsUpdatesAction.PARAM_REFRESH_REQUEST_CREATED;
import static google.registry.request.RequestParameters.extractEnumParameter;
import static google.registry.request.RequestParameters.extractOptionalIntParameter;
import static google.registry.request.RequestParameters.extractOptionalParameter;
import static google.registry.request.RequestParameters.extractRequiredParameter;
import static google.registry.request.RequestParameters.extractSetOfParameters;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@ -49,6 +54,17 @@ public abstract class DnsModule {
@DnsWriterZone
abstract String provideZoneName(@Parameter(RequestParameters.PARAM_TLD) String tld);
/**
* Provides a HashFunction used for generating sharded DNS publish queue tasks.
*
* <p>We use murmur3_32 because it isn't subject to change, and is fast (non-cryptographic, which
* would be overkill in this situation.)
*/
@Provides
static HashFunction provideHashFunction() {
return Hashing.murmur3_32();
}
@Provides
@Named(DNS_PULL_QUEUE_NAME)
static Queue provideDnsPullQueue() {
@ -81,6 +97,20 @@ public abstract class DnsModule {
return extractRequiredParameter(req, PARAM_DNS_WRITER);
}
@Provides
@Parameter(PARAM_LOCK_INDEX)
static int provideLockIndex(HttpServletRequest req) {
// TODO(b/72150053): Make non-optional once this cl has reached production for an hour
return extractOptionalIntParameter(req, PARAM_LOCK_INDEX).orElse(1);
}
@Provides
@Parameter(PARAM_NUM_PUBLISH_LOCKS)
static int provideMaxNumLocks(HttpServletRequest req) {
// TODO(b/72150053): Make non-optional once this cl has reached production for an hour
return extractOptionalIntParameter(req, PARAM_NUM_PUBLISH_LOCKS).orElse(1);
}
@Provides
@Parameter(PARAM_DOMAINS)
static Set<String> provideDomains(HttpServletRequest req) {