3

Does anyone have any links/resources on how to do unique value reservations in an eventually consistent environment?

Example: Users, on signup, get to choose their username. Even if two users are trying to grab the same name at the same time, only one should succeed.

I've got a couple of potential solutions floating around my head, but I was wondering if anyone has already done the legwork for this design.

Nelz
  • 103
  • 4
  • Here's what I'm seeing in my head as a first-pass idea: A two-phase process... In the first phase, I add a reservation request to a list/queue/whateverIHaveAccessTo. In the second phase, which only runs after a time window in which we can be sure that consistency in the list/queue/whatev has been achieved, we see if my request is the 'winning' one, and if it is I get the privilege of using the contested thing (username?), and if I am not the winning request, I must choose a new one. – Nelz Jul 25 '14 at 18:30

3 Answers3

0

Uniqueness constraints require serializability/linearizability. That makes it impossible to achieve in a non-serializable system. All AP systems in the CAP sense are non-serializable.

Eventual consistency is vaguely defined but it almost almost implies a non-serializable system. Therefore, your request is impossible to achieve.

Chose a consistent database to get the uniqueness guarantees you need and potentially replicate that data into your eventually consistent data store.

usr
  • 168,620
  • 35
  • 240
  • 369
  • I disagree. In an eventually consistent environment you can guarantee uniqueness **eventually**. One way is to use some sort of two-phase system, and involves waiting for your consistency window. I'm imagining a reservation/reservation-confirmation type of pattern... I was just wondering if anyone has already published something like that. – Nelz Jul 25 '14 at 14:10
  • Well, then the reservation-confirmation has to be consistent... If you require all parties of the system to agree one user name you require coordination for everyone. It was published that this is impossible to achieve. See the work of "aphyr" (search for that name). Fantastic articles. This is a complex topic. – usr Jul 25 '14 at 14:11
  • One additional comment: If you can guarantee that consistency can be obtained in a bounded amount of time I'm sure this is possible. But then you system is no longer available or consistent because you can't tolerate arbitrary message loss (for an arbitrary duration). – usr Jul 25 '14 at 21:36
0

This is one of those problems where the theoretical answer is just plain stupid. Yes, any unique identifier requires some form of serialization.

But in the real world it is very easy to extend an existing unique identifier to form a new one. The most obvious is your machine's public IP address and a timestamp. There can only be a single owner of an IP address at any time, therefore the combination is unique. You now just have to decide how many of these records you are allowed to create from one node in the precision of the timestamp.

Domain names also have the same characteristics, but are less compact. But they are more easily verified, which is why they are commonly used to form truly global namespaces for object classes.

-1

When you mentioned the username field, you reminded me of an old viral joke stating that the greatest problem humanity will have to solve 50 years from now is finding an available username on the internet.

The issue you are mentioning in your comment has to do with locking and concurrent inserts which is detailed here: http://dev.mysql.com/doc/refman/5.0/en/locking-issues.html

Now, as far as I am aware, insert statements are cached and stored in a queue prior to be executed, regardless of their similar time of arrival. So automatically one will get the unique value (e.g: the username), while the other won't. But realistically, the odds to have two users choosing the same username at the same atomic time are very, very low. There are a lot of things that need to work perfectly in order to test that even in a laboratory environment.

On a different note you can allow two users to register while having the same username. For example: Assume that you have an user account system where you allow an user to register with a username and a password. The username is restricted to the following characters: a to z, A to Z, 0 to 9 plus the special characters _(underscore) and .(full stop). You can concatenate the username (which is defined as not unique in your mysql table) with a special character (excepting _ and .) followed by an unique identifier that you have in your mysql table (let's say the user_id).

When the user tries to login, you compare his input with the set of all substring usernames (you only take the value prior to the special character you defined). Record the matches in an array, then check to see if the user password matches with any of the found users' password. If it does, then you log him in, if it doesn't then you don't.

Although I've seen the above in practice, I am quite against it. I would use the users' e-mail instead of an unique username. It is a much simpler and much cleaner solution since the e-mail is unique. There are no two users that have the same e-mail account, unless they share that address (for example addresses that sound like contact@xyzcompany.com).

R T
  • 1,038
  • 9
  • 17