etcd/

directory
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2018 License: Apache-2.0

README

Etcd quotas

Package etcd (and its subpackages) contain an etcd-based quota.Manager implementation, with a corresponding REST-based configuration service.

Usage

First, ensure both logserver and logsigner are started with the --etcd_servers and --quota_system=etcd flags, in addition to other flags. logserver must also be started with a non-empty --http_endpoint flag, so the REST quota API can be bound.

For example:

trillian_log_server \
  --etcd_servers=... \
  --http_endpoint=localhost:8091 \
  --quota_system=etcd

trillian_log_signer --etcd_servers=... --quota_system=etcd

If correctly started, the servers will be using etcd quotas. The default configuration is empty, which means no quotas are enforced.

The REST quota API may be used to create and update configurations.

For example, the command below creates a sequencing-based, global/write quota. Assuming an expected sequencing performance of 50 QPS, the max_tokens specified below implies a backlog of 4h.

curl \
  -d '@-' \
  -s \
  -H 'Content-Type: application/json' \
  -X POST \
  'localhost:8091/v1beta1/quotas/global/write/config' <<EOF
{
  "name": "quotas/global/write/config",
  "config": {
    "state": "ENABLED",
    "max_tokens": 288000,
    "sequencing_based": {
    }
  }
}
EOF

To list all configured quotas, run:

curl 'localhost:8091/v1beta1/quotas?view=FULL'

Quotas may be retrieved individually or via a series of filters, updated and deleted through the REST API as well. See quotapb.proto for an in-depth description of entities and available methods.

Maintenance and token exhaustion

During regular system operation, no quota-related maintenance should be required, as the system should generate at least as many tokens as it spends.

If token exhaustion occurs, there are a few built-in mechanisms that allow for manual intervention. The question of whether intervention is needed, though, is an important one and should be answered before any attempts are made to bypass the system. For example:

  • is the logsigner working properly and able to keep with the current demand?
  • is there a spike in requests that may justify the current token exhaustion?

For "genuine" token exhaustion (i.e. the system really is under a load it can't cope with), it may be beneficial to let the quota system deny requests until regular operation is resumed.

That said, the sections below describe actions that may taken to deal with token exhaustion. All examples use global/read as the quota in question; substitute the name as appropriate.

Resetting quotas

Resetting a quota restores its current token count to the configured max_tokens value.

curl -X PATCH \
  'localhost:8091/v1beta1/quotas/global/read/config?reset_quota=true'
Disabling quotas

Disabling a quota makes it inactive, effective immediately. Disabled quotas may be enabled again with a similar update (changing "DISABLED" to "ENABLED").

curl \
  -d '@-' \
  -s \
  -H 'Content-Type: application/json' \
  -X PATCH \
  'localhost:8091/v1beta1/quotas/global/read/config' <<EOF
{
  "config": {
    "state": "DISABLED"
  },
  "update_mask": ["state"]
}
EOF
Deleting quotas

Permanently deletes a quota. Consider disabling for a temporary solution.

curl -X DELETE 'localhost:8091/v1beta1/quotas/global/read/config'
Flags

The following flags apply to etcd quotas:

--quota_dry_run, when set to true, stops quota depletion from blocking requests. This applies to all quotas, so it's only recommended in early evaluations of the quota system.

--quota_increase_factor is related to token leakage protection. It applies only to sequencing-based quotas. If --quota_increase_factor is 1, each new leaf sequenced by logsigner restores exactly one token. If it's higher than 1, more tokens are restored per leaf batch. A value slightly higher than 1 (e.g. 1.1) is recommended, so there is some protection against token leakage without too much compromise of the quota system in exceptional situations.

--quota_max_cache_entries and --quota_min_batch_size are related to token caching. Some level of token caching (i.e. both flags having values > 0) is recommended to lessen the latency impact of rate limiting.

--quota_min_batch_size is the minimum number of tokens acquired from etcd. If a particular request demands fewer tokens than the minimal batch size, the remaining tokens are kept in memory, potentially saving new requests to etcd until those are consumed.

--quota_max_cache_entries determines how many quota Specs are cached. Tokens are cached per Spec using a LRU replacement policy. In case of systems with a high number of trees or users, the least used ones are evicted from the cache (and their tokens returned).

Monitoring

The following metrics are relevant when considering quota behavior:

Requests denied due to token shortage are labeled on interceptor_request_denied_count as insufficient_tokens. The ratio between denied_with_insufficient_tokens and interceptor_request_count is a strong indicator of token exhaustion.

General concepts

Trillian quotas have a finite number of tokens that get consumed by requests. Once a quota reaches zero tokens, all requests that would otherwise consume a token from it will fail with a resource_exhausted error. Tokens are replenished by different mechanisms, depending on the quota configuration (e.g, X tokens every Y seconds).

Quotas are designed so that a set of quotas, in different levels of granularity, apply to a single request.

A quota Spec identifies a particular quota and represents to which requests it applies. Specs contain a Group (global, tree and user) and Kind (read or write).

A few Spec examples are:

  • global/read (all read requests)
  • global/write (all write requests)
  • trees/123/write (write requests for tree 123)
  • users/alice/read (read requests made by user "alice")

Each request, depending on whether it's a read or write request, subtracts tokens from the following Specs:

read requests write requests
users/$id/read users/$id/write
trees/$id/read trees/$id/write
global/read global/write

Quotas that aren't explicitly configured are considered infinite and won't block requests.

Etcd quotas

Etcd quotas implement the concepts described above by storing the quota configuration and token count in etcd.

Two replenishment mechanisms are available: sequencing-based and time-based.

Sequencing-based replenishment is tied to logsigner's progress. A token is restored for each leaf sequenced from the Unsequenced table. As such, it's only applicable to global/write and trees/write quotas.

Time-based sequencing replenishes X tokens every Y seconds. It may be applied to all quotas.

MMD protection

Sequencing-based quotas may be used as a form of MMD protection. If the number of write requests accepted by Trillian going beyond the logsigner's configured processing capability, tokens will eventually get exhausted and the system will fail new write requests with a resource_exhausted error. While not ideal, this helps avoid an eventual MMD loss, which may be a graver offense than temporary loss of availability.

Both global/write and trees/write quotas may be used for MMD protection purposes. It's strongly recommended that global/write is set up as a last line of defense for all systems.

QPS limits

Time-based quotas effectively work as QPS (queries-per-second) limits (X tokens in Y seconds is roughly equivalent to X/Y QPS).

All quotas may be configured as time-based, but they may be particularly useful as per-tree (e.g. limiting test or archival trees) or as per-user.

Default quotas

Default quotas are pre-configured limits that get automatically applied to new trees or users.

TODO(codingllama): Default quotas are not yet implemented.

Quota users

User level quotas are applied to "quota users". Trillian makes no assumptions about what a quota user is. Therefore, initially, there's a single default user that is charged for all requests (note that, since no quotas are created by default, this user charges quotas that are effectively infinite).

TODO(codingllama): Allow personalities to specify the quota user to be charged. As of this moment, the only way to specify users would be to fork Trillian or make a PR.

Directories

Path Synopsis
Package etcdqm contains an etcd-based quota.Manager implementation.
Package etcdqm contains an etcd-based quota.Manager implementation.
Package quotaapi provides a Quota admin server implementation.
Package quotaapi provides a Quota admin server implementation.
Package quotapb contains definitions for quota API protos and RPC service.
Package quotapb contains definitions for quota API protos and RPC service.
Package storage contains storage classes for etcd-based quotas.
Package storage contains storage classes for etcd-based quotas.
Package storagepb is a generated protocol buffer package.
Package storagepb is a generated protocol buffer package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL