zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Redis综述

Redis 综述
2023-09-14 09:08:23 时间

  一、Redis简介

  • Redis是一款开源的、高性能的键-值存储数据结构服务器。
  • Redis采用了内存中数据集的方式。同时,Redis支持数据的持久化 (aof追加方式及rdb快照方式)。
  • Redis支持主从复制(master-slave replication)。
  • Redis具有丰富的客户端,支持现阶段流行的大多数编程语言。
  • Redis还具有其它一些特性,其中包括简单的事物支持(MULTI )、发布订阅 ( pub/sub),分布式锁(SETNX),键空间通知(KeySpaceNotification)等。

  二、Redis支持的数据类型

  (1)Key:非二进制安全的字符类型(not binary-safe strings)

  • key也是字符串类型,由于key不是binary safe的字符串,所以包含空格和换行的key是不允许的。
  • Key不要太长。太长的话占内存,查询慢。
  • Key不要太短。太短的话可读性差。

  (2)Value:String、List、Set、Sorted set、Hash

  • String是Redis最基本的类型,而且String类型是二进制安全的。 Redis的String可以包含任何数据。包括jpg图片或者序列化的对象。最大上限是1G大小。如果只用string类型,redis就可以被看作加上持久化特性的memcached。

  • List类型其实就是一个每个子元素都是String类型的双向链表。我们可以通过push、pop操作从链表的头部或者尾部添加删除元素。这使得List既可以用作栈,也可以用作队列。

  • Set是String类型的无序集合。Set元素最大可以包含(2的32次方-1)个元素。 Set元素不允许重复。Set的是通过Hash table实现的,Hash table会随着添加或者删除自动的调整大小。关于Set集合类型除了基本的添加删除操作,其他有用的操作还包含集合的取并集(union),交集(intersection),差集(difference)。

  • Sorted set和Set一样,也是String类型元素的集合,不同的是每个元素都会关联一个double类型的score。 Sorted set的实现是skip list和hash table的混合体。当元素被添加到集合中时,一个元素到score的映射被添加到hash table中,另一个score到元素的映射被添加到skip list并按照score排序,所以就可以有序的获取集合中的元素。
  • Hash是一个String类型的field和value的映射表。Hash特别适合用于存储对象。相较于将对象的每个字段存成单个String类型。将一个对象存储在Hash类型中会占用更少的内存,并且可以更方便的存取整个对象。

  三、Redis持久化快照(Snapshotting RDB)

  Redis是一个支持持久化的内存数据库,也就是说Redis需要经常将内存中的数据同步到磁盘来保证持久化,这是相对memcache来说的一个大的优势。

  Redis支持两种持久化方式:一种是 Snapshotting(快照)也是默认方式,一种是Append-only file(缩写aof)的方式。

  (1)Snapshotting(RDB)快照是默认的持久化方式。这种方式将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以配置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置:

  save 900 1  #900秒内如果超过1个key被修改,则发起快照保存

  save 300 10 #300秒内容如超过10个key被修改,则发起快照保存

  save 60 10000

  (2)Append-only file(aof)比快照方式有更好的持久化性,是由于在使用aof持久化方式时,Redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)。 当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。我们可以通过配置文件告诉redis我们想要通过fsync函数强制os写入到磁盘的时机。有三种方式如下(默认是:每秒fsync一次):

  appendonly yes                //启用aof持久化方式

       # appendfsync always      //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用

  appendfsync everysec     //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐

  # appendfsync no            //完全依赖os,性能最好,持久化没保证

  (3)RDB和AOF的比较

  • RDB:
    • 优点:
    1. RDB文件非常适合备份(因为是快照)
    2. RDB 非常适用于灾难恢复(因为是快照)
    3. RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快很多(因为不像AOF是一条一条write命令来执行的)
    4. RDB文件不容易损坏(因为保存频率慢)
    • 缺点:
    1. RDB 文件持久化频率过慢。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据
    2. 保存 RDB文件时比较耗时( 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作,save时间也不可能调整为很小)
  • AOF:
    • 优点:
    1. AOF持久化频率可以自己设置,保证不丢数据
    2. 当Redis 启动时, 如果 RDB 持久化和 AOF 持久化都被打开了, 那么程序会优先使用 AOF 文件来恢复数据集, 因为 AOF 文件所保存的数据通常是最完整的。
    • 缺点:
    1. 文件容易损坏(如停机造成了 AOF 文件出错)
    2. 不方便备份(AOF在不断变化,不好备份)
    3. 相同数据集下AOF文件大小要大于RDB(AOF文件是记录每条命令)

  (4)如果 AOF 文件出错了,怎么办?

  服务器可能在程序正在对 AOF 文件进行写入时停机, 如果停机造成了 AOF 文件出错(corrupt), 那么 Redis 在重启时会拒绝载入这个 AOF 文件, 从而确保数据的一致性不会被破坏。 恢复步骤:

  1. 将现有已经坏损的AOF文件额外拷贝出来一份。
  2. 执行"redis-check-aof --fix <filename>"命令来修复坏损的AOF文件。
  3. 用修复后的AOF文件重新启动Redis服务器。

  四、Redis集群模式

  (1)Sentinel 哨兵

  Redis3.0以前为了解决Redis主结点宕机,从结点不能立即上升为主结点继续提供服务的问题,Redis提供了Sentinel哨兵去监控整个Redis系统,如果有Redis主结点失效,Sentinel哨兵会发送命令给相应的从结点,将从结点提升为主结点继续提供服务。Sentinel哨兵是特殊的Redis实例。为了防止单点故障,Sentinel实例也需要部署多个(最少3个) 。如果需要分片存储,那么需由客户端实现分片算法,与Memcached的方式类似,客户端去实现键映射算法。

  (2)代理

  将代理中间件部署在客户端和Redis服务器的中间,将客户端发来的请求,进行一定的处理后(如分片),再转发给后端真正的Redis服务器。客户端不直接访问Redis服务器,而是通过代理中间件间接访问。该方案可大大简化客户端的实现,数据存取机制、Redis监控管理、故障转移都由代理中间件去实现。 缺点是会有20%的损耗性能。相比其它方案,需要部署Redis代理。

  (3)Redis Cluster

  集群最少3主3从,每个主结点也可以搭配多个从结点。该方案由服务端实现分布式,服务端有变化,客户端无感知。Redis 3.0及以上版本才支持Redis Cluster,解决了数据分片以及额外引入Sentinel或代理的问题。

  (4)Redis Cluster 部署建议

  建议3台主机互为主备,节省主机资源。集群失效的情况:

  • 集群基于leader选举模式,超过半数主节点挂掉,集群失效。
  • 如果集群任意master挂掉,且当前master没有slave,集群进入失效状态。