讓Redis資料集保持一致性

jieforest發表於2012-08-15
As you start using Redis more, you soon find yourself delving into redis' transactions. A traditional RDBMS' view of CAS (compare-and-set) transactions is:

- Lock down the entire database to writes, allowing just the one connection in the transaction to write

- Perform. a query to figure out which things need to change (Compare Step)

- Change those things (Set step)

- Release the lock (this happens automaticaly as part of your transaction completing)

Redis, on the other hand uses Optimistic Locking which makes CAS transactions look like:

- Start tracking stuff you think could change while you are in your transaction

- Perform. a query to figure out which things need to change (Compare Step)

- Execute the transaction to change those things (Conditional Set)

- Check to see if the transaction completed successfully

- Repeat from step 1 to re-run transaction or just abort

Step 1, where you start tracking stuff prior to doing anything is where Optimistic Locking and the more traditional Pessimistic Locking diverge in a pretty big way.

Optimistic Locking

The general idea behind optimistic locking is that you need to know before hand what you think might change while you are perform. a transaction and watch out for that. Pessimistic locking on the other hand, is a more heavy handed approach where you don’t want anything to change while you are in the middle of a transaction. 

Pessimistic locking, as you might’ve guessed, is more punishing on performance and forwrite heavy datastores like Redis that need to maintain high performance, it just is not an option. The downside with optimistic locking, though is that more of the heavy lifting falls on the engineer, who needs to put in a little more thought while dealing with transactions. Redis ships with a watch command that lets you specify what keys you want to keep an eye on, prior to running a multi-exec transaction.

An example

All this sounds great, but nothing beats a real-world example to see how to work with this and why it might be harder than you think. Recently, I was working on a task that required me to do just this — when a user logs into our app, figure all of that users facebook friends who are logged in, in our app and send that over.

The setup

The data in our app is structured in the following format:

- Users are hashes of the format “user|

- All currently logged-in users have their facebook ID’s stored in a “logged_in_fb_ids” set

- There is a facebook ID to user ID reverse look up hash map “fb_id_to_user_id_hash”

- Every user has a set of facebook friends ids that contains facebook id’s of people they are friends with on facebook — “fb_friend_ids_for_user|”

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/301743/viewspace-741026/,如需轉載,請註明出處,否則將追究法律責任。

相關文章