Redis的数据结构丰富,一般不会在功能性上造成困扰。但随着请求量的增加,SLA要求的提高,我们势必会对Redis进行一些改造和定制性开发。
Redis提供了主从、哨兵、cluster等三种集群模式,其中cluster模式为目前大多数公司所采用的方式。
但是,redis的cluster模式,有不少的硬伤。redis cluster采用虚拟槽的概念,把所有的key映射到 0~16383个整数槽内,属于无中心化的架构。但它的维护成本较高,slave也不能够参与读取操作。
它的主要问题,在于一些批量操作的限制。由于key被hash到多台机器上,所以mget、hmset、sunion等操作就非常的不友好,经常发生性能问题。
Redis的主从模式是最简单的模式,但无法做到自动failover,通常在主从切换后,还需要修改业务代码,这是不能忍受的。即使加上haproxy这样的负载均衡组件,复杂性也是非常高的。
哨兵模式在主从数量比较多的时候,能够显著的体现它的价值。一个哨兵集群,能够监控成百上千个集群,但是哨兵集群本身的维护是比较困难的。幸运的是,Redis的文本协议非常简单,在netty中,甚至直接提供了Redis的codec。自研一套哨兵系统,加强它的功能,是可行的。
Redis的特点是,不管什么数据,都一股脑地搞到内存里做计算,这对于有时间序列概念,有冷热数据之分的业务,造成了非常大的成本考验。为什么大多数开发者喜欢把数据存放在MySQL中,而不是Redis中?除了事务性要求以外,很大原因是历史数据的问题。
通常,这种冷热数据的切换,是由中间件完成的。我们上面也谈到了,Redis是一个文本协议,非常简单。做一个中间件,或者做一个协议兼容的Redis模拟存储,是比较容易的。
比如我们Redis中,只保留最近一年的活跃用户。一个好几年不活跃的用户,突然间访问了系统,这时候我们获取数据的时候,就需要中间件进行转换,从容量更大,速度更慢的存储中查找。
这个时候,Redis的作用,更像是一个热库,更像是一个传统cache层做的事情,发生在业务已经上规模的时候。但是注意,直到此时,我们的业务层代码,一直都是操作的Redis的api。它们使用这众多的函数指令,并不关心数据到底是真正存储在redis中,还是在ssdb中。
Redis还能玩很多花样。举个例子,全文搜索。很多人都会首选es,但Redis生态就提供了一个模块:RediSearch,可以做查询,可以做filter。
但我们通常还会有更多的需求,比如统计类、搜索类、运营效果分析等。这类需求与大数据相关,即使是传统的DB也不能胜任。这时候,我们当然要把Redis中的数据,导入到其他平台进行计算啦。
如果你选择的是Redis数据库,那么dba打交道的,就是rdb,而不是binlog。有很多的rdb解析工具(比如redis-rdb-tools),能够定期把rdb解析成记录,导入到hadoop等其他平台。
此时,rdb成为所有团队的中枢,成为基本的数据交换格式。导入到其他db后的业务,该怎么玩怎么玩,完全不会因为业务系统选用了Redis就无法运转。
大多数业务系统,跑在Redis上,这是很多一直使用MySQL做业务系统的同学所不能想象的。看完了上面的介绍,相信你能够对Redis能够实现的存储功能有个大体的了解。打开你的社交app、游戏app、视频app,看一下它们的功能,能够涵盖多少呢?
要强调的是,某些数据,并不是一定要落地到RDBMS才算安全,它们并不是一个强需求。
那既然Redis这么厉害,为什么还要有mysql、tidb这样的存储呢?关键还在于业务属性上。
如果一个业务系统,每次交互的数据,都是一个非常大的结果集,并涉及到非常复杂的统计、过滤工作,那么RDBMS是必须的;但如果一个系统,能够通过某个标识,快速定位到一类数据,这一类数据在可以预见的未来,是有限的,那就非常适合Redis存储
。
一个电商系统,选用Redis做存储就是作死,但一个社交系统就快活的多。在合适的场景选用合适的工具,才是我们应该做的。
但是一个系统,能否在产品验证期,就能快速的响应变化,快速开发上线,才是成功的关键。这也是使用Redis做数据库,所能够带来的最大好处。千万别被那概率极低的丢数据场景,给吓怕了。比起产品成功,你的系统即使是牢如钢铁,也一文不值。