How does the transaction in Redis

mercredi 23 janvier 2013

Working with Redis recently and that there was the need to change one key multiple threads simultaneously. To work with Redis to use php client Rediska. Even when I read the manual on Rediska see the section about the transaction , and now it's time to read carefully.



Do not know what to blame, or my poor knowledge of English, or my tugodumstvo, or incomprehensible documents, yet the documentation for transactions online Rediska and then on the website of the Redis I did not understand it locked, variable within a transaction, the key to the record before the execute () or not.
Yes, the documentation is both a description and examples «Optimistic locking using check-and-set» when used watch, but at the beginning of the official documentation site and Redis-written:

All the commands in a transaction are serialized and executed sequentially. It can never happen that a request issued by another client is served in the middle of the execution of a Redis transaction. This guarantees that the commands are executed as a single isolated operation.

After reading this I thought (of the cross just in case) that here it is just that no one in the middle of a transaction to change the values ​​of affected keys. But I was wrong and that it would have to understand a script similar to the one that is shown in the dock at the client site Rediska.

$ Options = array (
'Namespace' => 'Application_',
'Servers' => array (
array ('host' => '127 .0.0.1 ',' port '=> 6379,' db '=> 5)
)
);

require_once 'Rediska.php';

/ / Get rediska entity
$ Rediska = new Rediska ($ options);

for ($ i = 1; $ i <= 10000; $ i + +) {
/ / Start transaction
$ Transaction = $ rediska -> transaction ();

/ / Get current value
$ Value = $ rediska -> get ('test_value');

/ / Increment value
$ Value + +;

/ / Store new value
$ Transaction -> set ('test_value', $ value);

/ / Execute transaction
$ Transaction -> execute ();
}

echo $ rediska -> get ('test_value');


This script is run in two streams from the command line, ie, the idea in the end had to get the value of a key «test_value» of 20 thousand, but in reality, there is an average yield of about 12 thousand. Ie no blockage there.

Now a little modify a cycle by adding the watch:

for ($ i = 1; $ i <= 10000; $ i + +) {
for ($ j = 1; $ j <= 5; $ j + +) {
/ / Start transaction
$ Transaction = $ rediska -> transaction ();

/ / Watch
$ Transaction -> watch ('test_value');

/ / Get current value
$ Value = $ rediska -> get ('test_value');

/ / Increment value
$ Value + +;

/ / Store new value
$ Transaction -> set ('test_value', $ value);

/ / Execute transaction
try {
$ Transaction -> execute ();
} Catch (Rediska_Transaction_AbortedException $ e) {
continue;
}

break;
}
}


Ie in fact when a 5-Th eksepshena again trying to repeat the transaction. As a result, the 5-Tew repetitions in the average yield of 17 000, for example if we raise it to 10 will leave an average of 19 thousand.
This is of course special cases, in practice, is unlikely to be as many simultaneous changes and 5 reps in principle should be sufficient, but not in this case. The fact is that in fact the Redis has yet Mechanism (documented) to lock the keys affected by the changes.
Good or bad is not for me to decide to judge, I think everything depends on the problem, just wanted to show how it is.

0 commentaires:

Enregistrer un commentaire

 
© Copyright 2010-2011 GARMOBI All Rights Reserved.
Template Design by Herdiansyah Hamzah | Published by Borneo Templates | Powered by Blogger.com.