1.Redis简介:
Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。
字符串: String 是 Redis最简单的数据结构,可以存储字符串、整数或者浮点数。最常见的应用场景就是对象缓存,计数器(博客文章的阅读量、评论数、点赞数),分布式系统生成自增长ID。
List列表:相当于 Java 语言里面的 LinkedList。
LinkedList优点:插入性能高,不管是从末尾插入还是中间插入
LinkedList缺点:随机读取数据性能差,例如LinkedList.get(10),这种操作,性能就很低,因为他需要从头开始遍历整个链表,直到找到下标符合的元素为止。常见的应用场景:异步队列(右边进左边出),任务轮询(RPOPLPUSH),文章列表(lrange key 0 9)
Hash:相当于Java语言的HashMap,内部实现结构上与JDK1.7的HashMap一致,底层通过数据+链表实现。主要使用场景:记录博客中某个博主的主页访问量、博主的姓名、联系方式、住址。
set集合:相当于Java的HashSet。Redis 中的 set 类型是一种无序集合,集合中的元素没有先后顺序。HashSet就是基于HashMap来实现的,HashSet其实就是说一个集合,里面的元素是无序的,他里面的元素不能重复的,HashMap的key是无顺序的,你插入进去的顺序,跟你迭代遍历的顺序是不一样的,而且HashMap的key是没有重复的,HashSet直接基于HashMap实现的。主要使用场景:微博抽奖(移除并返回集合中的一个随机元素),QQ标签:一个用户多个便签,共同关注(交集),共同好友(交集)
有序集合:sorted set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。使得它类似于Java的TreeSet和HashMap的结合体。主要使用场景:排行榜,订单支付超时(下单时插入,member为订单号,score为订单超时时间戳,然后写个定时任务每隔一段时间执行zrange)。
4.Redis的持久化方案由哪些?
1)RDB 持久化
RDB持久化可以使用save或bgsave,为了不阻塞主进程业务,一般都使用bgsave,流程:
Redis 进程会 fork 出一个子进程(与父进程内存数据一致)。父进程继续处理客户端请求命令,由子进程将内存中的所有数据写入到一个临时的 RDB 文件中。完成写入操作之后,旧的 RDB 文件会被新的 RDB 文件替换掉。
下面是一些和 RDB 持久化相关的配置:
save 60 10000:如果在 60 秒内有 10000 个 key 发生改变,那就执行 RDB 持久化。
stop-writes-on-bgsave-error yes:如果 Redis 执行 RDB 持久化失败(常见于操作系统内存不足),那么 Redis 将不再接受 client 写入数据的请求。
rdbcompression yes:当生成 RDB 文件时,同时进行压缩。
dbfilename dump.rdb:将 RDB 文件命名为 dump.rdb。
dir /var/lib/redis:将 RDB 文件保存在/var/lib/redis目录下。
当然在实践中,我们通常会将stop-writes-on-bgsave-error设置为false,同时让监控系统在 Redis 执行 RDB 持久化失败时发送告警,以便人工介入解决,而不是粗暴地拒绝 client 的写入请求。
RDB持久化的优点:
RDB持久化文件小,Redis数据恢复时速度快
子进程不影响父进程,父进程可以持续处理客户端命令
子进程fork时采用copy-on-write方式,大多数情况下,没有太多的内存消耗,效率比较好。
RDB 持久化的缺点:
子进程fork时采用copy-on-write方式,如果Redis此时写操作较多,可能导致额外的内存占用,甚至内存溢出
RDB文件压缩会减小文件体积,但通过时会对CPU有额外的消耗
如果业务场景很看重数据的持久性 (durability),那么不应该采用 RDB 持久化。譬如说,如果 Redis 每 5 分钟执行一次 RDB 持久化,要是 Redis 意外奔溃了,那么最多会丢失 5 分钟的数据。
2)AOF 持久化
可以使用appendonly yes配置项来开启 AOF 持久化。Redis 执行 AOF 持久化时,会将接收到的写命令追加到 AOF 文件的末尾,因此 Redis 只要对 AOF 文件中的命令进行回放,就可以将数据库还原到原先的状态。
与 RDB 持久化相比,AOF 持久化的一个明显优势就是,它可以提高数据的持久性 (