评论删除后,数据将无法恢复
Over the last few months, I've been thinking about and implementing transactions for Lua scripting in Redis. Not everyone understands why I'm doing this, so let me explain with a bit of history.
MySQL and Postgres
In 1998-2003 if you wanted to start a serious database driven web
site/service and didn't have money to pay Microsoft or Oracle for their
databases, you picked either MySQL or Postgres. A lot of people picked
MySQL because it was faster, and much of that was due to the MyISAM
storage engine that traded performance for a lack of transaction
capability - speed is speed. Some people went with Postgres because
despite its measurably slower performance on the same hardware, you
could rely on Postgres to not lose your data (to be fair, the data loss
with MySQL was relatively rare, but data loss is never fun).
A lot of time has passed since then; MySQL moved on from MyISAM as the
default storage engine to InnoDB (which has been available for a long
time now), gained full transaction support in the storage engine, and
more. At the same time, Postgres got faster, and added a continually
expanding list of features to distinguish itself in the marketplace. And
now the choice of whether to use MySQL or Postgres usually boils down
to experience and preference, though occasionally business or regulatory
needs dictate other choices.
TL;DR; data integrity
In a lot of ways, Redis up to now is a lot like MySQL was back before
InnoDB was an option. There is already a reasonable best-effort to
ensure data integrity (replication, AOF, etc.), and the introduction of
Lua scripting in Redis 2.6 has helped Redis grow up considerably in its
capabilities and the overall simplification of writing software that
uses Redis.
Comparatively, Lua scripting operates very much like stored procedures
in other databases, but script execution itself has a few caveats. The
most important caveat for this post is that once a Lua script has
written to the database, it will execute until any one of the following
occurs:
The script exits naturally after finishing its work, all writes have been applied
The script hits an error and exits in the middle, all writes that were done up to the error have occurred, but no more writes will be done from the script
Redis is shut down without saving via SHUTDOWN NOSAVE
You attach a debugger and "fix" your script to get it to do #1 or #2 (or some other heroic deed that allows you to not lose data)
To anyone who is writing software against a database, I would expect
that you agree that only case #1 in that list is desirable. Cases #2,
#3, and #4 are situations where you can end up with data corruption
(cases #2 and #4) and/or data loss (cases #3 and #4). If you care about
your data, you should be doing just about anything possible to prevent
data corruption and loss. This is not philosophy, this is doing your
job. Unfortunately, current Redis doesn't offer a lot of help here. I
want to change that.
Transactions in Lua
I am seeking to eliminate cases #2, #3, and #4 above, replacing the entire list with:
The script exits naturally after finishing its work, all writes have been applied
The script exits with an error, no changes have been made (all writes were rolled back)
No data loss. Either everything is written, or nothing is written. This
should be the expectation of any database, and I intend to add it to the
expectations that we all have about Redis.
The current pull request
is a proof of concept. It does what it says it does, removing the need
to lose data as long as you either a) explicitly run your scripts using
the transactional variants, or b) force all Lua script calls to have
transactional semantics with a configuration option.
There are many ways the current patch can be made substantially better,
and I hope for help from Salvatore (the author of Redis) and the rest of
the community.
评论删除后,数据将无法恢复
评论(8)
引用来自“肥迪”的评论
当要进行一些后数据分析时Lua会很好用,项目开少用。