Redis存储总用String?你大概错过了更优的使用方法
副标题[/!--empirenews.page--]
Redis为我们提供了5种数据类型,基本上我们使用频率最高的就是String,而对其他四种数据类型使用的频次稍弱于String。原因在于:
这里我们不打算罗列这5种数据类型的使用方法,因为这些资料网上有很多。我们主要讨论这5种数据类型的功能特点,弄清楚它们分别适合用于处理哪些现实的业务场景,我们又该如何组合性使用这5种数据类型,找到解决复杂cache问题的最优方案。 一、Redis的数据类型及特点我们来简要了解一下String、List、Hash、Set及Zset: 1)String String是Redis提供的字符串类型。可以针对String类型独立设置expire time,通常用来存储长字符串数据,比如某个对象的json字符串。 在使用上,String类型最巧妙的是可以动态拼接key。通常我们可以将一组id放在Set里,然后动态查找String还是否存在,如果不存在说明已经过期或者由于数据修改主动delete了,需要再做一次cache数据load。 虽然Set无法设置item的过期时间,但是我们可以将Set Item与String Key关联来达到相同的效果。 下图中的左边是一个key为Set:order:ids的Set集合,它可能是一个全量集合,也可能是某个查询条件获取出来的一个集合: 有时候复杂点的场景需要多个Set集合来支撑计算,在Redis服务器里可能会有很多类似这样的集合。这些集合我们可以称为功能数据,这些数据是用来辅助cache计算的,当进行各种集合运算之后会得出当前查询需要返回的子集,最后我们才会去获取某个订单真正的数据。 这些String:order:{orderId}字符串key并不一定是为了服务一种场景,而是整个系统最底层的数据,各种场景最后都需要获取这些数据。那些Set集合可以认为是查询条件数据,用来辅助查询条件的计算。 Redis为我们提供了TYPE命令来查看某个key的数据类型,如String类型:
2)List List在提高throughput的场景中非常适用,因为它特有的LPUSH、RPUSH、LPOP、RPOP功能可以无缝的支持生产者、消费者架构模式。 这非常适合实现类似Java Concurrency Fork/Join框架中的work-stealing算法(工作窃取)。 注:Java Fork/Join框架使用并行来提高性能,但是会带来由于并发take task带来的race condition(竞态条件)问题,所以采用work-stealing算法来解决由于竞争问题带来的性能损耗。 下图中模拟了一个典型的支付callback峰值场景: 在峰值出现的地方一般我们都会使用加buffer的方式来加快请求处理速度,这样才能提高并发处理能力,提高through put。 支付gateway收到callback之后不做任何处理直接交给分发器。 分发器是一个无状态的cluster,每个node通过向注册中心pull handler queue list,也就是获取下游处理器注册到注册中心里的消息通道。每一个分发器node会维护一个本地queue list,然后顺序推送消息到这些queue list即可。 这里会有点小问题,就是支付gateway调用分发器的时候,是如何做load balance?如果不是平均负载可能会有某个queue list高出其他queue list。 而分发器不需要做soft load balance,因为哪怕某个queue list比其他queue list多也无所谓,因为下游message handler会根据work-stealing算法来窃取其他消费慢的queue list。 Redis List的LPUSH、RPUSH、LPOP、RPOP特性确实可以在很多场景下提高这种横向扩展计算能力。 3)Hash Hash数据类型很明显是基于Hash算法的,对于项的查找时间复杂度是O(1)的,在极端情况下可能出现项Hash冲突问题,Redis内部是使用链表加key判断来解决的。具体Redis内部的数据结构我们在后面有介绍,这里就不展开了。 Hash数据类型的特点通常可以用来解决带有映射关系,同时又需要对某些项进行更新或者删除等操作。如果不是某个项需要维护,那么一般可以通过使用String来解决。 如果有需要对某个字段进行修改,使用String很明显会多出很多开销,需要读取出来反序列化成对象然后操作,然后再序列化写回Redis,这中间可能还有并发问题。 那我们可以使用Redis Hash提供的实体属性Hash存储特性,我们可以认为Hash Value是一个Hash Table,实体的每一个属性都是通过Hash得到属性的最终数据索引。 下图使用Hash数据类型来记录页面的a/bmetrics: 左边的是首页index的各个区域的统计,右边是营销marketing的各个区域统计。 在程序里我们可以很方便的使用Redis的atomic特性对Hash某个项进行累加操作。
使用Redis Hash Increment进行原子增加操作。HINCRBY命令可以原子增加任何给定的整数,也可以通过HINCRBYFLOAT来原子增加浮点类型数据。 4)Set Set集合数据类型可以支持集合运算,不能存储重复数据。 Set最大的特点就是集合的计算能力,inter交集、union并集、diff差集,这些特点可以用来做高性能的交叉计算或者剔除数据。 (编辑:湘西站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |