Redis数据库

140 阅读8分钟

Redis数据库

Redis同其他缓存产品相比的特点

  • Redis支持数据的持久化。
  • Redis支持简单丰富据结构的存储。
  • Redis支持数据的备份。

Redis优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子性 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

Redis数据类型

类型简介特性场景
String
(字符串)
二进制安全可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M---
Hash
(字典)
键值对集合,即编程语言中的Map类型适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值(Memcached中需要取出整个字符串反序列化成对象修改完再序列化存回去)存储、读取、修改用户属性
List
(列表)
链表(双向链表)增删快,提供了操作某一段元素的API1,最新消息排行等功能(比如朋友圈的时间线) 2,消息队列
Set
(集合)
哈希表实现,元素不重复1、添加、删除,查找的复杂度都是O(1) 2、为集合提供了求交集、并集、差集等操作1、共同好友 2、利用唯一性,统计访问网站的所有独立ip 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐
Sorted Set
(有序集合)
将Set中的元素增加一个权重参数score,元素按score有序排列数据插入集合时,已经进行天然排序1、排行榜 2、带权重的消息队列
bitmap在线用户统计
HyperLogLog近似去重
Geo计算距离

Redis持久化方式

  • RDB RDB持久化是指用数据集快照的方式记录redis数据库的所有键值对。

两个命令:SAVE命令会阻塞主进程来完成写文件,BGSAVE命令会创建子进程来完成写文件,主进程会继续处理命令。

优点

1.只有一个文件dump.rdb,方便持久化。

2.容灾性好,一个文件可以保存到安全的磁盘。

3.性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。

4.相对于数据集大时,比AOF的启动效率更高。

缺点

1.数据安全性低,通过配置save参数来达到定时的写快照,比如 每900 秒有1个键被修改就进行一次快照,每600秒至少有10个键被修改进行快照,每30秒有至少10000个键被修改进行记录。所以如果当服务器还在等待写快照时出现了宕机,那么将会丢失数据。

2.fork子进程时可能导致服务器停机1秒,数据集太大。

配置

# RDB文件名
dbfilename "dump.rdb"
# RDB文件和AOF文件路径
dir "/usr/local/var/db/redis"

# 当在规定的时间内,Redis发生了写操作的个数满足条件,会触发发生BGSAVE命令。
# save <seconds> <changes>
# 当用户设置了多个save的选项配置,只要其中任一条满足,Redis都会触发一次BGSAVE操作,比如:900秒之内至少一次写操作、300秒之内至少发生10次写操作、60秒之内发生至少10000次写操作都会触发发生快照操作
save 900 1
save 300 10
save 60 10000
  • AOF AOF持久化是指所有的命令行记录以redis命令请求协议的格式保存为aof文件。

优点

1.数据安全,aof持久化可以配置appendfsync属性,有always,每进行一次命令操作就记录到aof文件中一次;everySec,就是每秒内进行一次文件的写操作;no就是不进行aof文件的写操作。

2.通过append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。

3.AOF机制的rewrite模式,用来将过大的aof文件缩小,实现原理是将所有的set 通过一句set 命令总结,所有的SADD命令用总结为一句,这样每种命令都概括为一句来执行,就可以减少aof文件的大小了。(注意,在重写的过程中,是创建子进程来完成重写操作,主进程每个命令都会在AOF缓冲区和AOF重写缓冲区进行保存,这样旧版aof文件可以实现数据最新,当更新完后将重写缓冲区中的数据写入新的aof文件中然后就可以将新的文件替换掉旧版的文件。

缺点

1.文件会比RDB形式的文件大。

2.数据集大的时候,比rdb启动效率低。

配置

# redis默认关闭AOF机制,可以将no改成yes实现AOF持久化
appendonly no
# AOF文件
appendfilename "appendonly.aof"
# AOF持久化同步频率,always表示每个Redis写命令都要同步fsync写入到磁盘中,但是这种方式会严重降低redis的速度;everysec表示每秒执行一次同步fsync,显示的将多个写命令同步到磁盘中;no表示让操作系统来决定应该何时进行同步fsync,Linux系统往往可能30秒才会执行一次
# appendfsync always
appendfsync everysec
# appendfsync no


# 在日志进行BGREWRITEAOF时,如果设置为yes表示新写操作不进行同步fsync,只是暂存在缓冲区里,避免造成磁盘IO操作冲突,等重写完成后在写入。redis中默认为no  
no-appendfsync-on-rewrite no   
# 当前AOF文件大小是上次日志重写时的AOF文件大小两倍时,发生BGREWRITEAOF操作。  
auto-aof-rewrite-percentage 100  
#当前AOF文件执行BGREWRITEAOF命令的最小值,避免刚开始启动Reids时由于文件尺寸较小导致频繁的BGREWRITEAOF。  
auto-aof-rewrite-min-size 64mb  
# Redis再恢复时,忽略最后一条可能存在问题的指令(因为最后一条指令可能存在问题,比如写一半时突然断电了)
aof-load-truncated yes
#Redis4.0新增RDB-AOF混合持久化格式,在开启了这个功能之后,AOF重写产生的文件将同时包含RDB格式的内容和AOF格式的内容,其中RDB格式的内容用于记录已有的数据,而AOF格式的内存则用于记录最近发生了变化的数据,这样Redis就可以同时兼有RDB持久化和AOF持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据)。
aof-use-rdb-preamble no

redis集群

image.png

Sentinel哨兵模式

image.png

Cluster集群模式

image.png

redis事务

www.jianshu.com/p/479398a8e…

redis分布式锁

分布式锁的优化

eg: 一条正常的请求下单链路需要耗时20ms,其中包括与redis集群通信时间,一秒只能支持50个请求,现在需要支持100个,怎么去做

redis穿透、雪崩

缓存穿透,是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。

缓存雪崩,是指在某一个时间段,缓存集中过期失效。

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

淘汰策略

策略描述
volatile-lru从已设置过期时间的KV集中优先对最近最少使用(less recently used)的数据淘汰
volitile-ttl从已设置过期时间的KV集中优先对剩余时间短(time to live)的数据淘汰
volitile-random从已设置过期时间的KV集中随机选择数据淘汰
allkeys-lru从所有KV集中优先对最近最少使用(less recently used)的数据淘汰
allKeys-random从所有KV集中随机选择数据淘汰
noeviction不淘汰策略,若超过最大内存,返回错误信息

redis常见问题

1、redis作为消息队列为什么不能保证100%的可靠性?

如何用Redis实现分布式锁,可能遇到的问题和解决办法

redis的hash怎么实现的?

zk分布锁和redis分布式锁的区别?

redis分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能。
zk分布式锁,获取不到锁,注册个监听器即可,不需要不断主动尝试获取锁,性能开销较小。
另外一点就是,如果是redis获取锁的那个客户端出现bug挂了,那么只能等待超时时间之后才能释放锁;而zk的话,因为创建的是临时znode,只要客户端挂了,znode就没了,此时就自动释放锁。

redis如何删除bigKey redis的 zset 为什么用跳表实现?为什么不用二叉树

redis的list结构?

www.cnblogs.com/javazhiyin/…