redis简介
数据存储的结构类型:
String, List, Set, ZSet(Sorted Set:有序集合), Hash五种数据结构的存储
特点:
开源,ANSI语言,C语言,BSD协议,支持网络,可持久化日志型,键值对类型.它通常被称为数据结构服务器
持久化数据:
Redis持久化类型:
持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
RDB(Redis DataBase)和AOF(Append-only file)
Redis通讯协议:
内容是redis通讯协议(RESP)格式的命令文本存储。
Redis通讯协议(RESP):
RESP(BS协议): 客户端和服务端之前使用的一种通讯协议
RESP的特点: 实现简单、快速解析、可读性好
Redis架构特点:
单机版:
特点:简单
缺点:内存容量有限,处理能力有限,无法高可用。
主从复制:
特点:只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据降低master读压力(转移至从库),master/slave角色,主从数据相同
缺点:无法保证高可用,没有解决master写的压力
哨兵:
特点:在主服务器下线时自动进行故障转移(监控,提醒,自动故障迁移)[保证高可用]
缺点:主从模式,切换主从时需要的时间段内会丢数据
集群(proxy型):
Twemproxy是一个Twitter开源的一个redis和memcache快速/轻量级代理服务器;
Twemproxy是一个快速的单线程代理程序,支持Memcached ASCII协议和redis协议。
特点:1.多种 hash 算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins
2.支持失败节点自动删除
3.后端Sharding分片逻辑对业务透明
缺点:增加了新的 proxy,需要维护其高可用。(failover逻辑需要自己实现,可扩展性差)
集群(直连型):
从redis3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构
特点:1.数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
2.节点可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
3.高可用性,部分节点不可用时,集群仍可用。通过增加Slave做备份数据副本
4.实现故障自动Failover,节点之间通过 Gossip 协议交换状态信息.
5.无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。
缺点:资源隔离性较差,容易出现相互影响的情况(数据异步复制,不保证数据的强一致性)
Redis常用命令:
keys (pattern) :查询所有key
setnx(key value):如果key已经存在返回 0,nx 是 not exist 的意思
setex(key seconds value):将值value关联到key,并将key的过期时间设为seconds(以秒为单位)。
expire mset getset(返回oldValue,没有就返回nil)
persist(key):取消过期时间
... ...
Redis配置异步队列:
使用redis里的list或者set数据结构,rpush生产消息,lpop消费消息。(先入先出原则)
在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitMQ等。
问题:
①生产者速度大于消费者消费速度,消息队列长度会一直增大,时间久了会占用大量内存空间。
②睡眠时间过长,这样不能处理一些时效性的消息,睡眠时间过短,也会在连接上造成比较大的开销。
解决方案:brpop和blpop实现阻塞读取
Redis的订阅/消费:
服务端可以使用publish去推送消息,客服端使用subscribe去消费
订阅的时候subscribe()和psubscribe()的第二个参数支持可变参数,也就是可以实现订阅多个频道。要注意的是,订阅获得的内容(三部分:信息类型如"message",信息频道如channel1:1,信息主体如内容)
重写JedisPubSub 的onPMessage方法,可以将message直接区分后获取
发布订阅执行订阅之后该线程处于阻塞状态,线程不会终止,如果终止线程需要退订,需要调用JedisPubSub的unsubscribe()方法
缓存穿透和雪崩:
如果对数据的一致性要求很高,那么就不能使用缓存
缓存穿透:传统方法是先查询缓存,若是不存在,则去查DB,若是DB也不存在,则不作缓存(攻击者会不断查询一个不存在的key,从而对数据库造成很大的压力)
解决方法1:对数据库不存在的数据,也提供一个缓存,并设置短期的过期时间,如30s
解决方法2:布隆过滤器,将所有可能存在一个bitmap中进行过滤(就不会去查不存在的数据)
缓存雪崩1号:大批量数据在同一时间端内,缓存同时失效(如双十一的商品信息缓存)
解决方法:不同分类商品,缓存不同周期。(即在时间周期后补加一个random时间)
缓存雪崩2号:缓存服务器某个节点宕机或断网(严重)
解释:自然形成的缓存雪崩,一定是在某个时间段集中创建缓存,那么那个时候数据库能顶住压力,这个时候,数据库也是可以顶住压力的。无非就是对数据库产生周期性的压力而已。而缓存服务节点的宕机,对数据库服务器造成的压力是不可预知的,很有可能瞬间就把数据库压垮。
缓存击穿:是指一个key非常热点,在不停的扛着大并发,在某一时刻key失效
解决方法:"爆款"商品key永不过期(不需要使用mutex_key互斥锁)
mutex_key互斥锁(针对缓存穿透):
1 public String get(key) {
2 String value = redis.get(key);
3 if (value == null) { //代表缓存值过期
4 //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
5 if (redis.setnx(key_mutex, 1, 3 * 60) == 1) { //代表设置成功
6 value = db.get(key);
7 redis.set(key, value, expire_secs);
8 redis.del(key_mutex);
9 } else { //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
10 sleep(50);
11 get(key); //重试
12 }
13 } else {
14 return value;
15 }
16 }

浙公网安备 33010602011771号