分布式缓存redis⽅案_JAVA分布式Redis缓存
1、什么是Redis
Redis采⽤的是基于内存的采⽤的是单进程单线程模型的KV数据库,由C语⾔编写。官⽅提供的数据是可以达到100000+的qps
2、Redis基本数据类型
Redis⽬前⽀持5种数据类型,分别是:
String(字符串)
List(列表)
Hash(字典)
Set(集合)
Sorted Set(有序集合)
下⾯就分别介绍这五种数据类型及其相应的操作命令。
2.1、String(字符串)
String是简单的 key-value 键值对,value 不仅可以是 String,也可以是数字。String在redis内部存储默认就是⼀个字符串,被redisObject所引⽤,当遇到incr,decr等操作时会转成数值型进⾏计算,此时redisObject的encoding字段为int。
String在redis内部存储默认就是⼀个字符串,被redisObject所引⽤,当遇到incr,decr等操作时会转成数值型进⾏计算,此时redisObject 的encoding字段为int。
应⽤场景:
String是最常⽤的⼀种数据类型,普通的key/value存储都可以归为此类,这⾥就不所做解释了。
String(字符串)
2.2、List(列表)
Redis列表是简单的字符串列表,可以类⽐到C++中的std::list,简单的说就是⼀个链表或者说是⼀个队列。可以从头部或尾部向Redis列表添加元素。列表的最⼤长度为2^32 - 1,也即每个列表⽀持超过40亿个元素。
Redis list的实现为⼀个双向链表,即可以⽀持反向查和遍历,更⽅便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是⽤的这个数据结构。
应⽤场景
Redis list的应⽤场景⾮常多,也是Redis最重要的数据结构之⼀,⽐如twitter的关注列表、粉丝列表等都可以⽤Redis的list结构来实现,再⽐如有的应⽤使⽤Redis的list类型实现⼀个简单的轻量级消息队列,⽣产者push,消费者pop/bpop。
List(列表)
2.3、Hash(字典)
Redis Hash对应Value内部实际就是⼀个HashMap,实际这⾥会有2种不同实现,这个Hash的成员⽐较少时Redis为了节省内存会采⽤类似⼀维数组的⽅式来紧凑存储,⽽不会采⽤真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增⼤时会⾃动转成真正的HashMap,此时encoding为ht。
Hash(字典)
2.4、Set(集合)
Redis的Set是string类型的⽆序集合。集合成员是唯⼀的,这就意味着集合中不能出现重复的数据。
Redis 中 集合是通过哈希表实现的,所以添加,删除,查的复杂度都是O(1)。
集合中最⼤的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
Set(集合)
2.5、Sorted Set(有序集合)
Redis 有序集合和集合⼀样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联⼀个double类型的分数。redis正是通过分数来为集合中的成员进⾏从⼩到⼤的排序。
有序集合的成员是唯⼀的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查的复杂度都是O(1)。 集合中最⼤的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
Sorted Set(有序集合)
3、Redis单线程好处
代码更清晰,处理逻辑更简单不⽤去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁⽽导致的性能消耗不存在多进程或者多线程导致的切换⽽消耗CPU所以redis线程是安全的
4、单进程单线程弊端
⽆法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善;
5、Redis应⽤场景
5.1令牌(Token)⽣成
5.2短信验证码
5.3发布订阅
相当于消息系统,ActiveMQ,RocketMQ等⼯具类似,但是个⼈觉得简单⽤⼀下还⾏,如果对于数据⼀致性要求⾼的话还是⽤RocketMQ 等专业系统。
由于redis把数据添加到队列是返回添加元素在队列的第⼏位,所以可以做判断⽤户是第⼏个访问这种业务
redis支持的五种数据类型队列不仅可以把并发请求变成串⾏,并且还可以做队列或者栈使⽤
5.4分布式锁
验证前端的重复请求(可以⾃由扩展类似情况),可以通过redis进⾏过滤:每次请求将request Ip、参数、接⼝等hash作为key存储redis(幂等性请求),设置多长时间有效期,然后下次请求过来的时候先在redis中检索有没有这个key,进⽽验证是不是⼀定时间内过来的重复提交
秒杀系统,基于redis是单线程特征,防⽌出现数据库“爆破”
全局增量ID⽣成,类似“秒杀”
5.5计数器
诸如统计点击数等应⽤。由于单线程,可以避免并发问题,保证不会出错,⽽且100%毫秒级性能!
5.6缓存(热点数据)
热点数据(经常会被查询,但是不经常被修改或者删除的数据),⾸选是使⽤redis缓存,毕竟强⼤到冒泡的QPS和极强的稳定性不是所有类似⼯具都有的,⽽且相⽐于memcached还提供了丰富的数据类型可以使⽤,另外,内存中的数据也提供了AOF和RDB等持久化机制可以选择,要冷、热的还是忽冷忽热的都可选。
结合具体应⽤需要注意⼀下:很多⼈⽤spring的AOP来构建redis缓存的⾃动⽣产和清除,过程可能如下:
Select 数据库前查询redis,有的话使⽤redis数据,放弃select 数据库,没有的话,select 数据库,然后将数据插⼊redis
update或者delete数据库钱,查询redis是否存在该数据,存在的话先删除redis中数据,然后再update或者delete数据库中的数据
上⾯这种操作,如果并发量很⼩的情况下基本没问题,但是⾼并发的情况请注意下⾯场景:
为了update先删掉了redis中的该数据,这时候另⼀个线程执⾏查询,发现redis中没有,瞬间执⾏了查询SQL,并且插⼊到redis中⼀条数据,回到刚才那个update语句,这个悲催的线程压根不知道刚才那个该死的select线程犯了⼀个弥天⼤错!于是这个redis中的错误数据就永远的存在了下去,直到下⼀个update或者delete。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论