1.场景需求
实际项目中,使用Redis进行数据缓存、在读多写少的情况下:
如何搭建缓存?如何实现缓存一致性?如何实现业务解耦?
2.为何需要缓存?
MySQL数据库存储中,具备完整的ACID特性、但是同样也会带来一定的性能问题。高并发场景下,大量的请求直接打到数据库中会造成宕机、服务崩溃的问题。
所以,需要添加一层数据缓冲层、在读多写少的环境中,将大量的请求通过Redis缓冲层进行分担是一个很不错的思路。
3.缓存问题
使用了Redis作为缓存层、分担数据库压力的同时,不可避免的需要考虑数据一致性问题。
Redis应用过程中,我们无法实现强一致性、只能做到最终一致性。
依赖于何种机制进行更新呢?
4.解决方案
1.方案-完全依赖key过期
这种方案依赖于Redis中的key过期更新、MySQL更新的同时、Redis并不会进行更新。实现简单、但会存在过大未及时更新的过期数据。
特点:简单、易维护。
缺点:完全依赖于key过期时间、需要做时间偏移、且长时间存在脏数据、更新时延长。
2.方案-部分依赖key过期
是对上述方案的一种优化、通过Redis中的key过期进行兜底、但在MySQL更新的同时也进行Redis数据的更新。
特点:更新时延小
缺点:MySQL更新失败则退化到方案一、性能消耗(同时更新连接多)
3.方案-消息队列
这种方案是对前一种方案的进一步优化、在MySQL与Redis更新之间架设一层消息队列。MySQL更新的同时、将Redis更新丢入到Kafka中、通过下游服务进行更新。
特点:连接数少、部分解耦
缺点:无法保证数据时效性(并发执行无法保证数据有序更新)
4.方案-binlog+消息队列
此方案中,通过搭建独立的服务监听MySQL的数据变动、模拟搭建MySQL的Slave从服务、通过Binlog日志的变动分析来更新Redis中的数据。
搭建Slave从服务、监听MySQL中的binlog日志文件、分析数据推入到Kafka中、再通过下游服务进行消息消费同步。
特点:完全解耦、无时效、延时较低
缺点:维护成本高