New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document that locks aren't really locks #11457
Comments
@aphyr |
If you use lock to start a long running process, this child process will not even be terminated even if the lẹase is lost. As a result, etcd lock is only usable for short tasks. |
2 tasks
mcassaniti
added a commit
to mcassaniti/msdha
that referenced
this issue
Apr 15, 2021
The initial design for MSDHA expected that etcd locks would remain held for the lifetime of the process run under the lock. It also expected the process to be stopped and the lease to be dropped all at the same time if the etcd lock was somehow lost. See [here](etcd-io/etcd#11457 (comment)) for more information. The new design instead relies on detecting that there is no current master rather than using a lock to hold the master role. MSDHA will (in order): * wait MSDHA_TTL*2 seconds * Acquire the etcd lock * Determine if a master already exists by now otherwise stop * Promote the node * Set the state to master in etcd * Run a background job to wait MSDHA_MASTER_TTL seconds before terminating the container The logic for restarting the etcd change detection was also re-written to prevent losing events between restarts.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As a part of our Jepsen testing, we've demonstrated that etcd's locks aren't actually locks: like all "distributed locks" they cannot guarantee mutual exclusion when processes are allowed to run slow or fast, or crash, or messages are delayed, or their clocks are unstable, etc. For example, this workload uses etcd's locks to protect read-modify-write updates to perfect
shared state. Here, the shared state is stored in memory, so we don't have to
worry about latency or failures, but realistically, we'd be sharing state in
something like a filesystem, object store, third-party database, etc.
https://github.com/jepsen-io/etcd/blob/c4787f4e71495584c276e998107ee811160dcea7/src/jepsen/etcd/lock.clj#L150-L163
This is directly adapted from the etcd 3.2 announcement, which demonstrates
using locks to increment a file on disk: https://coreos.com/blog/etcd-3.2-announcement:
Instead of updating a file on disk, our workload adds unique integers to a set
by reading a mutable variable, waiting some random amount of time from 0 to 2
seconds, and setting the variable to the value that was read, plus the given
integer.
We use the same lock acquisition and release strategy as described before: we
grant a lease with a 2-second TTL, keep it alive indefinitely using a watchdog
thread, then acquire a lock with that lease:
https://github.com/jepsen-io/etcd/blob/c4787f4e71495584c276e998107ee811160dcea7/src/jepsen/etcd/lock.clj#L33-L37
When we partition away leader nodes every 10 seconds or so, this workload
exhibits both lost updates and stale reads (due to the in-memory state
"flickering" as competing lock holders overwrite each other). This 60-second
test lost 10/42 successfully completed writes:
This problem was exacerbated by #11456, but fundamentally cannot be fixed. Users cannot use etcd as a naive locking system: they must carefully couple a fencing token (e.g. the etcd lock key revision number) to any systems they interact with in order to preserve exclusion boundaries.
etcd could remove locks altogether, but I don't think that's strictly necessary: it's still useful to have something which is mostly a lock. For example, users could use locks to ensure that most of the time, one node, rather than dozens, is performing a specific computation. Instead, I'd like to suggest changing the documentation to make these risks, and the correct use of locks, explicit. In particular, I think these pages could be revised:
https://coreos.com/blog/etcd-3.2-announcement
#10096
https://github.com/etcd-io/etcd/blob/master/Documentation/dev-guide/api_concurrency_reference_v3.md
https://github.com/etcd-io/etcd/tree/master/etcdctl#concurrency-commands
The text was updated successfully, but these errors were encountered: