Redis 分布式锁的实现
在 Redis 的常见应用中,分布式锁是一个老生常谈的问题,本文主要讲讲怎么去实现一个分布式锁(最近真·写了不少 Lua 脚本)。
加锁
对于加锁操作,理论上应该是:
- 尝试加锁,如果成功,则记录锁,并且返回 true
- 如果失败,则不更新锁,返回 false
在 Redis 的常见应用中,分布式锁是一个老生常谈的问题,本文主要讲讲怎么去实现一个分布式锁(最近真·写了不少 Lua 脚本)。
对于加锁操作,理论上应该是:
限流也是一个系统中老生常谈的话题了,因为资源不是无限的,因此系统总会达到一个瓶颈,我们不可能接受无限的流量直到系统崩溃,于是也就有了限流策略。
一般来说,我们有几种方法可以来对系统进行评估:
Redis 是我们常见的缓存解决方案,但是使用不当的 Redis 同样会造成系统瓶颈。
要启用慢日志分析,首先先要对慢查询记录进行设置:
# 命令执行耗时超过 5 毫秒,记录慢日志
CONFIG SET slowlog-log-slower-than 5000
# 只保留最近 500 条慢日志
CONFIG SET slowlog-max-len 500
实在不知道该编什么名字,总之先复习一下缓存吧。本文讲的重点是服务端缓存,尤其是 Redis 相关的设计。
众所周知的是,我们的业务数据多数都会选择存储在 DB 里,但数据库本身是一个吞吐量有限的单点,在实际的高并发场景下,我们肯定不可能让所有的流量都流向 DB,因此在这种情况下,业务往往会涉及一些缓存来缓解 DB 的压力。
具体的来说,从客户端到服务端,链路的每一个节点都能具有缓存的能力。比如客户端的 HTTP Cache、边缘节点的 CDN 缓存,再到服务端缓存,包括内存缓存、Redis 缓存等等,在开头我们说过,重点是服务端缓存,因此我们会对客户端缓存暂且不表。(反正一言以蔽之也就是强缓存和协商缓存)。
我们经常会被问到这样一个问题:在一个下单流程中,如何保证数据的一致性。
如果我们在单服务单库中运行,那么很简单,使用数据库的事务就可以了。
但是正常来说,现在的所有服务都会采用微服务的架构,也就是说一个下单流程中,「订单服务」到「库存锁定」到「生成账单」到「支付交易」到「回调变更状态」,这几步将会有多个服务来共同完成。
此时我们必然不能让用户的任何一步失败,又或者必须保证失败后回滚一定成功,否则用户钱扣了,交易却没成功;或者造成了超卖,这些都会造成严重客诉。
为此才会引入分布式事务这个概念,也就是保障多个事务之间的一致性,要么全部成功,要么全部失败。
本文讲的都是比较基础的点,原理点到为止,适合人群为数据库小白,希望能够从数据库层面进行一些优化的同学。
最近在做旧项目改造的时候发现了很多不合理的索引设计,或者干脆就没有设计索引,开发者仿佛把在线业务的表当做了离线表那样想怎么查就怎么查,导致了整个接口相当缓慢,甚至有可能拖垮整个服务 / DB。
于是我发现一些很常规的优化似乎其实并不是每个人都很清楚,所以今天就来聊聊 SQL 的索引优化。
因为我们的项目都是 MySQL / MongoDB 的,而我基本也只学了 MySQL,因此这里以 MySQL 为主,MongoDB 为辅来进行索引设计的解读。