为什么在 Redis 实现 Lua 脚本事务?

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介:

在刚过去的几个月中,我一直在构思并尝试在 redis 中实现 lua 脚本的事务功能。没有多少人理解我的想法,所以我将通过一些历史为大家做下解释。

MySQL 与 Postgres

在 1998-2003 年间,如果你想运行一个正规的数据库驱动的网站/服务,但又没有足够的资金购买微软或 Oracle 的数据库,你可以选择 MySQL 或 Postgres 。很多人都选择了 MySQL,因为它速度较快——主要是因为 MyISAM 存储引擎没有提供事务功能以此来换取性能,但速度确实很快。另一些人转向 Postgres,因为虽然在相同硬件上其性能明显低于 MySQL,但 Postgres 不会丢失数据(说实话,MySQL 数据丢失的情况非常少见,但丢了可不是闹着玩的)。

就这样凑合着过了很久;MySQL 将其默认的存储引擎从 MyISAM 过渡到了 InnoDB (其实很早就有了),这样它的存储引擎也得到了完整的事务支持和其他功能。与此同时,Postgres 也变快了,并添加了一个持续扩展的功能列表来使自己与众不同。现在对于 MySQL 与 Postgres 的选择只看个人的体验与偏好,除了有时业务需要或领导决定使用其他选择。

数据完整性

从很多方面来看,Redis 很像当初采用 InnoDB 前的 MySQL。而 Redis 采用了一种很合理的方式来保证数据完整性(复制,AOF 等),并且从 Redis2.6 开始引入的 Lua 脚本在功能与易用性方面为 Redis 的成长提供了很大助力。

相对来说,Lua 脚本与其他数据库中的存储过程很相似,但脚本的执行有些许不同。在本文中最重要的一点就是一旦将脚本写入数据库,它会一直执行直到以下任一种情况出现:

  1. 完成所有工作,所有写操作处理完成后脚本会自动退出。
  2. 脚本运行时出错并中途退出,所有以前执行的写操作都已发生,但不会再有其他写操作。
  3. Redis 通过 SHUTDOWN NOSAVE 关闭时(不保存)。
  4. 你附加了调试器来“使”脚本完成 #1 与 #2 (或其他手段来保证不会丢失数据)。

对于使用数据库开发软件的人,我想你也认同只有情景 #1 是最理想的。情景 #2,#3,#4 都会导致数据异常(#2 与 #4)和/或数据丢失(#3 和 #4)。如果你很重视数据,你应该尽可能地阻止数据异常与丢失。这不是哲学,而是工作(This is not philosophy, this is doing your job)。但很遗憾目前的 Redis 也帮不了你多少。所以我决定改变这种情况。

实现 Lua 脚本事务

我尝试解决上面列表中的 #2,#3,#4 问题,最终像下面这样:

脚本完成所有的工作,处理完写操作后正常退出

脚本执行过程中遇到错误退出,不更改任何数据(所有写操作都回滚)

无论有没有写入数据,都不会有数据丢失。这应该是所有的数据库都希望做到的,我打算把这个加到 Redis 中,因为我们都希望 Redis有 这个功能。

目前的 pull request 只是一个概念性的证明。也就是说,为了避免数据丢失,你要么 a) 显式使用事务的变体运行脚本,要么 b) 强制所有 Lua 脚本调用带配置选项的事务语义。

文章转载自 开源中国社区 [http://www.oschina.net]

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
打赏
0
0
0
0
325
分享
相关文章
|
5月前
|
Redis 事务
10月更文挑战第18天
60 1
Redis压测脚本及持久化机制
Redis压测脚本及持久化机制简介: Redis性能压测通过`redis-benchmark`工具进行,可评估读写性能。持久化机制包括无持久化、RDB(定期快照)和AOF(操作日志),以及两者的结合。RDB适合快速备份与恢复,但可能丢失数据;AOF更安全,记录每次写操作,适合高数据安全性需求。两者结合能兼顾性能与安全性,建议同时开启并定期备份RDB文件以确保数据安全。
34 9
【📕分布式锁通关指南 03】通过Lua脚本保证redis操作的原子性
本文介绍了如何通过Lua脚本在Redis中实现分布式锁的原子性操作,避免并发问题。首先讲解了Lua脚本的基本概念及其在Redis中的使用方法,包括通过`eval`指令执行Lua脚本和通过`script load`指令缓存脚本。接着详细展示了如何用Lua脚本实现加锁、解锁及可重入锁的功能,确保同一线程可以多次获取锁而不发生死锁。最后,通过代码示例演示了如何在实际业务中调用这些Lua脚本,确保锁操作的原子性和安全性。
62 6
【📕分布式锁通关指南 03】通过Lua脚本保证redis操作的原子性
|
5月前
|
Redis 脚本
10月更文挑战第18天
57 3
Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
通过本文的介绍,我们详细讲解了 Lua 脚本在 Redis 中的作用、`eval` 命令的使用方法以及 `redis.call` 和 `redis.pcall` 的区别和用法。通过合理使用 Lua 脚本,可以实现复杂的业务逻辑,确保操作的原子性,并减少网络开销,从而提高系统的性能和可靠性。
82 13
|
3月前
|
公司用什么软件监控电脑:Lua 脚本在监控软件扩展功能的应用
在企业环境中,电脑监控软件对保障信息安全、提升效率至关重要。Lua 脚本在此类软件中用于扩展功能,如收集系统信息、监控软件使用时长及文件操作,向指定服务器发送数据,支持企业管理和运营。
66 6
|
3月前
|
Redis事务长什么样?一文带你全面了解
Redis事务是一组命令的有序队列,通过MULTI、EXEC、WATCH和DISCARD等命令实现原子性操作。事务中的命令在EXEC执行前不会实际运行,而是先进入队列,确保所有命令要么全部成功,要么全部失败。此外,Redis还支持Lua脚本实现类似事务的操作,通常更简单高效。事务适用于购物车结算、秒杀活动、排行榜更新等需要保证数据一致性的场景。
60 0
|
5月前
|
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
114 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
301 0
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
65 2
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等