Redis and ACID transactions

3,207 views
Skip to first unread message

Christian Steiner

unread,
Sep 15, 2011, 7:17:56 AM9/15/11
to Redis DB
Hi all,

I know that this topic has probably already been discussed multiple
times ;) however will give it another try, since I'd like to be able
to use Redis as my one and only persistence mechanism for OLTP
applications if it would support ACID transactions. I'm aware that
this would need to be achieved through "usage patterns", supported by
a client library - if possible at all.

To set the stage I'd like to compare the current transactional
behavior of Redis [single instance] + AOF with the ACID properties.

Atomicity: Is currently guaranteed through MULTI, EXEC.
Consistency: As long as one only uses MULTI, EXEC (transactions) to
change data in Redis, consistency is also given. This could be
enforced by a client-library.
Isolation: Adding WATCH with MULTI, EXEC also guarantees isolation,
not in a classical SERIALIZABLE way but in a way most SQL systems act
by default today.
Durability: If you use AOF and set it to fsync with every
"write" (always) command then durability is guaranteed as well. Is
fsync also done with commands that do not change data (like GET)?

Do I miss anything important?

If we then increase the complexity and add master-slave replication to
improve on the HA capabilities of our system we'd have to re-evaluate
the setup. In order to guarantee ACID transactions in a master/slave
setup one would have to build functionality into the client library
that would publish transaction-id to the master - as a last statement
before the exec and subscribe on the slave. Once the client receives
the message from the slave it knows that the transaction has completed
successfully.

Does that make sense?

If all my assumptions are correct, I'd also like to know whether it
makes sense from your point of view to use Redis as the only
persistence mechanism for an OLTP application. My theoretical idea
behind this is to benefit from the cache-like read performance but
also have ACID transactions with only 1 persistence system.

An alternative would be to build some sort of a distributed read-write
cache with redis and a traditional dbms...

Thanks for you comments on this matter.
Christian

Ingvar Bogdahn

unread,
Sep 15, 2011, 9:18:06 AM9/15/11
to redi...@googlegroups.com
Hi,

I'd like to point out that even if Redis comes close to "actual" ACID, there is one important thing to remember: you cannot have conditionals within a transaction, that depend on temporal result of that same transaction. This is rather rare, but was a dealbreaker for me. 
Regarding transactions in a master/slave distribution, I think it's simple: everything transactional should go to the master. Sharding doesn't allow transactions (unless only a subset of keys have to support transactions, then you can use keytags). Slaves are mainly useful for read-only accesses and can also relieve the master of the persistence. If transactions are important to you, if you have a big portion of writes, and most of those writes are within transactions, then maybe redis master-slave is not the perfect tool of distribution. 

I'd be terribly interested, if upcoming Redis-cluster allows distributed transactions? Couldn't find anyhting on that. Do you know?

hth,
ingvar

Jak Sprats

unread,
Sep 15, 2011, 5:28:08 PM9/15/11
to Redis DB
Hi Ingvar & Christian,

Redis does not support Rollbacks. So if you have 5 commands w/in a
MULTI/EXEC and command 3 fails, commands 1 & 2 will not be rolled
back.

Redis is single threaded and commands w/in a MULTI/EXEC stream are
done in an isolated fashion, so this type of Rollback does not make
much sense in redis where it does make some sense in a traditional
RDBMS w/ many threads .... i.e. this type of Rollback is needed in
multi-threaded apps to create isolation, but in single-threaded apps,
you can roll your own rollbacks for the rare cases when you need to.

Here is an example, in a lua script (in psuedocode, not with the
KEYS[] array).
function give_money_to_poor(richid, poorid, amount)
local rich_guys_money = redis("decrby", "balance_" .. richid,
amount);
local poor_guys_money = redis("incrby", "balance_" .. poorid,
amount);
if (poor_guys_money > rich_guys_money) then -- that just isnt right -
> ROLLBACK
redis("incrby", "balance_" .. richid, amount);
redis("decrby", "balance_" .. poorid, amount);
end
end

So the example function is brain-dead on several levels but the point
should be clear, for the rare cases where you need a RDBMS-like
rollback ... if it is not too complex, you can just manually code the
rollback in a LUA function.

Its a hack, but if this is a deal-breaker, and it happens rarely, and
the logic is not that complex, it can un-deal-break

- jak



On Sep 15, 7:18 am, Ingvar Bogdahn <ingvar.bogd...@googlemail.com>
wrote:

Ingvar Bogdahn

unread,
Sep 16, 2011, 3:24:53 AM9/16/11
to redi...@googlegroups.com
Hi Jak,

Ah, cool finally! I was looking for some LUA code examples,
particularly those that improve transactions.
Forgot to mention the rollbacks of course, that was the second problem point.
I'll look into this, but for the transaction-internal dependencies my
problem is that sometimes the condition is not known at the moment the
transaction is sent, and which does not depend on code outside
redis/lua but some other java logic.. Have to check for way to
workaround that.

thanks a lot for your answer!

ingvar

2011/9/15 Jak Sprats <jaks...@gmail.com>:

> --
> You received this message because you are subscribed to the Google Groups "Redis DB" group.
> To post to this group, send email to redi...@googlegroups.com.
> To unsubscribe from this group, send email to redis-db+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
>
>

Christian Steiner

unread,
Sep 16, 2011, 4:54:51 AM9/16/11
to Redis DB
Hi Ingvar and Jak,

Many thanks for your replies.

So my learning's from your reply:
Yes its possible to use Redis (Master/Slave) for ACID transactions
(including rollback) under the following conditions:
- AOF is set to always on the master
- All the transactions are scripted in LUA and the rollback logic (if
required) is factored into it.

Igvar: Regarding the upcoming Redis Cluster and its capability for
"distributed transactions". I read the CLUSTER readme in design-docs.
As far as I understand the design all the current commands are still
supported with redis cluster so one could think that if you stick to
the same principles MULTI..EXEC or EVAL.. then the behavior regarding
consistency will remain intact... but I'm not really sure if my
assumptions are correct... since I expect the MULTI...EXEC harder to
implement when the keys are distributed over multiple servers..

Thanks,
Christian


On 16 Sep., 09:24, Ingvar Bogdahn <ingvar.bogd...@googlemail.com>
wrote:
> Hi Jak,
>
> Ah, cool finally! I was looking for some LUA code examples,
> particularly those that improve transactions.
> Forgot to mention the rollbacks of course, that was the second problem point.
> I'll look into this, but for the transaction-internal dependencies my
> problem is that sometimes the condition is not known at the moment the
> transaction is sent, and which does not depend on code outside
> redis/lua but some other java logic.. Have to check for way to
> workaround that.
>
> thanks a lot for your answer!
>
> ingvar
>
> 2011/9/15 Jak Sprats <jakspr...@gmail.com>:

Ingvar Bogdahn

unread,
Sep 16, 2011, 10:29:26 AM9/16/11
to redi...@googlegroups.com
Hi again,


> So my learning's from your reply:
> Yes its possible to use Redis (Master/Slave) for ACID transactions
> (including rollback) under the following conditions:
> - AOF is set to always on the master

why do you say AOF always? According to the information embedded in
the redis config file, AOF set to always is very slow. It emphasizes
that aof every second is a good compromise, but of course this depends
on your use case needs.

> - All the transactions are scripted in LUA and the rollback logic (if
> required) is factored into it.

beware that LUA scripting (eval) is not yet available in every client.
e.g. jedis, the Java client, doesn't support Lua yet.

I'd be interested in your experiences with LUA transaction scripts

best,
ingvar

Salvatore Sanfilippo

unread,
Sep 16, 2011, 10:36:02 AM9/16/11
to redi...@googlegroups.com
On Thu, Sep 15, 2011 at 3:18 PM, Ingvar Bogdahn
<ingvar....@googlemail.com> wrote:
> I'd be terribly interested, if upcoming Redis-cluster allows distributed
> transactions? Couldn't find anyhting on that. Do you know?

Hello Ingvar,

we'll start without any MULTI/EXEC support for Cluster (unless they
are all about a single key).
Basically we'll support only operations that are Cluster Obvious.
We'll see later if we'll be able to add transactions to the mix, but
the plan is to start with a reasonable subset of Redis commands.

Other things that will not be supported (at least initially, unsure
about the future) are commands operating on multiple keys.

Cheers,
Salvatore

--
Salvatore 'antirez' Sanfilippo
open source developer - VMware

http://invece.org
"We are what we repeatedly do. Excellence, therefore, is not an act,
but a habit." -- Aristotele

Christian Steiner

unread,
Sep 16, 2011, 11:18:27 AM9/16/11
to Redis DB
Hi Ingvar,

If you want to be as close to ACID as possible it make sense to fsync
on every write (or on every EXEC in our case, but there is no such
option ;) so if you want to make sure you don't loose any data on a
redis or machine crash you'd use AOF always. However I agree that the
probability is rather low that either event happens between the 1s
delay and your last write... A command to FSYNC as a last step in the
transaction would be cool.. or an AOF setting that would FSYNC after
the EXEC.. I remember there was I discussion on the list at one
point.. but I can't remember the outcome.

I plan to write my own client anyway. I'll let you know about my
experiences with LUA transactions.

Thanks,
Christian



On 16 Sep., 16:36, Salvatore Sanfilippo <anti...@gmail.com> wrote:
> On Thu, Sep 15, 2011 at 3:18 PM, Ingvar Bogdahn
>
Reply all
Reply to author
Forward
0 new messages