NoSQL——redis

一、no sql 的三大特点

  1. kv 的键值对结构(多种具有不同数据模型的产品,都与 kv 有关系);
  2. cache,就是缓存,缓存是不同 no sql 产品功能的主要体现形式。也就是主要的数据都存在于内存中,以保证访问速度;
  3. persistence,持久化。所有的 no sql 必须实现数据的持久化功能。也就是内存中的数据必须能够在磁盘中永久的保存下来,从而保证在下一次需要使用时能够迅速的使用。
  • kv 模型:以字符作为 key,用 key 来表示 value 值。v 的变化很大。这种模型适合存放需要快速检索的数据。因此它是作为系统缓存使用的主要模型。如:memcached,redis,tair 等。
  • 文档模型:可以理解为 js 中的对象,所以文档模型的基础是 BSON 结构的数据模型。BSON 很像 JSON,它属于安全的二进制数据(表示的是一个字符串,但是字符串的一些格式化的字符不会被解释,例如\n就表示字符串\n,不表示换行),它表示数据也是 kv 结构。代表产品:mongodb,用来存放大量的频繁使用的,对安全性要求不高的数据。
  • 列式模型:基于现代大数据分布式文件模型的 no sql 应用。它的基础仍然是 kv。

二、CAP 理论

  • CAP 是分布式系统的事务属性,在一个分布式存储(no sql,关系数据)的系统中,事务的三大特性(C、A、P)最多只能同时满足其中的两个,比如 AP,CP,AC。
    • C:Consistency, 一致性,也是数据的正确性,所有节点在同一时间具有相同的数据;
    • A:Availability,可用性,无论请求的处理是成功还是失败,必须得到响应;
    • P:Partition tolerance,分区容错性,无论通讯是否失败都要得到正确的结果。
  • AC,保证一致性和可用性,限制了系统的扩展。
  • CP,保证一致性和分区容错性,允许网络丢包或中断,但性能不高。
  • AP,保证可用性和分区容错性,满足不了一致性。

三、BASE 原则

  • BA,基本可用,服务降级,去除附属功能,保证核心功能。
  • S,软状态,达到一定程度的一致性。
  • E,最终一致性。
  • 基于 BASE 原则,关系型数据库要求一定要达到强一致性,允许牺牲可用性。no sql 允许弱一致,因此可用性比关系型数据库更好,扩展性也更强。
  • 总结:BASE 是在 CAP 基础之上所确定下来的,在设计分布式系统的架构时,一般都要按照 BASE 原则来进行设计。BASE 原则的核心思想就是合理的取舍,让系统的各方面达到一定的平衡。

四、redis 缓存数据库

  • remote dictional server ,远程词典服务器。
  1. 针对 key 的操作
    • keys * 列出所有的 key,在生产环境下,不要贸然使用该命令。
    • exists 判断 key 是否存在。
    • type 返回 key 的数据类型。
    • set 设置 key 和 value。
    • del 删除指定的 key。
    • dbsize 返回当前数据库 key 的数量,redis 默认有 16 个数据库。
    • select 选择数据库。
    • flushdb 清空当前数据库中所有的 key。
    • flushall 清空所有数据库中的 key。
    • swapdb 互换两个数据库的数据
  2. 针对 string 类型的操作
    • set 和 get 分别是赋值和取值。
    • incr 和 decr 可对数字字符串进行加一减一操作。
    • incrby 和 decrby 可对数字字符串进行加值操作,需指定。
    • mset 和 mget 一次设置和取出多个值。
    • strlen key 得到字符串的长度。
    • setrange 将字符串从某个位置替换。
    • getrange 得到子串。
  3. 针对 hash 类型的操作
    • hset 和 hget 设置和获取值。
    • hmset 和 hmget 设置和获取多个值
    • hestnx 当且仅当该key中域不存在时会设置值。
    • hlen 返回该key中域的数量。
    • hstrlen 返回给定域相关值的字符串长度。
    • hincrby 和 hincrbyfloat 前者加整数,后者可加小数。
    • hkeys 获取该key所有的域。
    • hvalues获取该key所有域的值。
    • hgetall 获取该key所有的域和值。
  4. list
    • lpush 和 rpush 在表头和表位插入,没有会创建。
    • lpushx 和 rpushx 在表头和表位创建,没有什么也不做。
    • lpop 和 rpop 在表头和表位弹出元素。
    • rpoplpush 将原表最后一个元素弹出并插入和目标表的表头。
    • lrem key count value 其中 count > 0 从表头开始,count < 0 从表尾开始,移除 count的绝对值 个与 value 相等的值,count = 0 表示移除所有与 value 相等的值。
    • llen 和 lindex 返回列表长度和返回列表中下标为 index 的元素。
    • linsert key BEFORE|AFTER pivot value 插入一个值在某个位置
    • lset 将下标为 index 的元素值设置为 value。
    • lrange 和 ltrim 返回一个区域内的元素和保留一个区域内的元素。
  5. set
    • sadd 和 apop 插入和弹出。
    • sismember 判断元素是否为该集合的成员。
    • srandmember key [ count ] 如果没有 count 返回一个随机元素,count > 0 且小于集合大小,返回包含 count 个不同元素的数组,count 大于集合大小,返回整个集合;count < 0 返回的数组元素可能会重复出现。
    • srem 移除集合中的一个或多个元素。
    • smove 将源集合某个元素移动到目标集合。
    • scard 返回集合元素的数量。
    • smembers 返回集合所有的成员。
    • sinter、sunion,sdiff 返回集合的交、并和差集。
  6. zset
    • zadd 将一个或多个元素及其 score 值加入到有序集合中。
    • zscore 返回有序集合中指定元素的 score 值。
    • zincrby 为有序集合的成员的 score 值加上一个增量。
    • zcard 返回有序集合的大小。
    • zcount key min max 返回一个区间内的元素数。
    • zrange key start stop [withscores] 返回指定区间内的元素,默认按 score 从小到大排序,加上 withscores 表示从大到小。
    • zrank 返回有序集合从小到大指定元素的排名。
    • zrevrank 返回有序集合从大到小指定元素的排名。
    • zrem 移除有序集合一个或多个成员。

五、redis 的持久化

  • redis 的持久化就是把内存中的数据(kv)永久地保存到磁盘上,可以在后续的运行再进行加载使用。因此,在执行持久化功能时,尽量地不丢失数据,尽少的影响主进程对客户端的操作。
  1. snapshot(快照),采用快照的方式可以把数据持久化为磁盘上的 .rdb 文件,在 redis 中,rdb(就是指快照) 是默认的方式。
  2. rdb 文件是二进制数据,采用紧凑格式来存放所有的数据,这样文件可以尽量小一些。
  3. 与 rdb 相关的配置项:
    • save <seconds> <changes> 这是执行持久化的时机的配置命令,seconds 表示经过的秒数,changes 表示数据发生改变的次数。
    • save “” 表示不做 rdb 持久化,其它例如 save 900 1;save 300 10;save 60 10000 等。可以写很多个,只要满足就会被执行。这是自动的方式,老的持久化的数据就会被当前的数据所覆盖。
    • rdbcompression yes 是否对 rdb 文件进行压缩,默认为需要压缩。
    • dbfilename dump.rdb 指定持久化后的文件名称。
    • dir ./ 指定持久化文件所在的目录,默认在当前目录下。
    • rdbchecksum yes 在加载持久化文件前需不需要做校验。
    • stop-writes-on-bgsave-error yes 当持久化过程中发生错误,是否停止针对客户端的数据改变操作。
  4. 执行 rdb 的时机
    • 手工的方式,如果用户在客户端执行 save 或者 bgsave 命令,rdb 操作马上进行。如果执行的是 save 则执行的是前台持久化,此时服务器不执行任何客户端的请求直到持久化完成,如果是 bgsave,则执行后台持久化,此时服务器仍然正常工作,所有客户端的请求都会被执行。在生产环境下严禁执行 save。
    • 与当前命令有关的情况,如果执行了 flushdb 或 flushall,马上执行 rdb,此时该文件是空的。
    • 如果执行关闭服务的命令 shutdown,也会马上执行 rdb。
    • 通过配置的方式让 rdb 在条件达到的情况下执行。
  5. 从 rdb 文件中恢复数据。
    • 当服务器重启时(挂掉后的重新开机,正常的关闭服务,安装新的机器等),如果需要立刻把持久化的数据加载到缓存中,此时就要用到 rdb 文件。在启动服务器时,如果指定的目录下有 rdb 文件(配置中指定名称),就会把该文件中的数据恢复到缓存中。利用这种启动时恢复的机制可以实现通常的数据备份操作。
    • 此时的数据备份就是拿到当前缓存的快照保存到 rdb 文件中。按照系统备份的规范,备份的文件必须异地保存。
    • 对于生产环境下的异地备份,应该对备份的文件做加密操作。把备份放在一个需要密码才能获取的位置。比如云对象存储。
  6. 采用 rdb 进行持久化的优点:
    • 优点:
      1. 每个指定的时刻都可以备份,可以恢复到已备份某个时刻的状态;
      2. rdb 是一个紧凑的单一文件,可以很方便的传送到另一个远端数据中心,适合于灾难恢复;
      3. rdb 持久化方式可以最大化 redis 的性能;
      4. 与 AOF 相比,在恢复大的数据集的时候,rdb 方式会更快一些。
    • 缺点:
      1. 通过配置的方式来指定持久化的条件,执行的时间间隔是离散的,这种备份总是会丢失一部分数据,丢失数据的多少与设置的参数有关;
      2. rdb 需要经常 fork 子进程来保存数据集到硬盘上,当数据集比较大时,fork 的过程非常耗时,可能会导致 redis 在一些毫秒级内不能响应客户端的请求;如果数据集巨大并且 CPU 性能不是很好的情况下,这种情况会持续1秒。
  7. 采用 append-only 的方式,实现持久化
    • 与 rdb 完全不同,它生成的文件内容是文本内容,相当于是命令的日志,保存的就是改变数据的命令。
    • 配置内容(默认关闭):
      • appendonly no 改为 yes,则可以采用 aof 的方式进行持久化;
      • appendfilename “appendonly.aof” 指定保存文件的文件名。
      • 三种方式:
        1. appendfsync always 每次改变都保存
        2. appendfsync everysec 每秒一次
        3. appendfsync no 交给操作系统执行
      • no-appendfsync-on-rewrite no 在重写 aof 文件时,不再接收客户端发出的改变请求,它与性能有关系。如果为 yes,可能会丢失一些命令。
        • bgrewiteaof 命令,aof 文件有时会很大,该命令用来当文件很大时,通过改变其中的一些命令让文件变小,
      • auto-aof-rewrite-percentage 100 如果当前最新的 aof 文件的长度比上次的 aof 文件大一倍,自动执行 rewrite 操作。
      • auto-aof-rewrite-min-size 64mb 如果当前最新的 aof 文件的大小达到了指定阀值,自动执行 rewrite 操作。最小是 2G,最好是 4G 以上。
      • aof-load-truncated yes 指 redis 在恢复时,会忽略最后一条可能存在问题的指令。默认值 yes 。即在 aof 写入时,可能存在指令写错的问题(突然断电,写了一半),这种情况下,yes 会 log 并继续,而no会直接恢复失败。
    • 利用 aof 进行数据恢复
      • 如果 rdb 和 aof 文件都存在,在启动时,恢复的是 aof 文件中的内容。
    • 使用 bgrewriteaof 命令压缩原有的文件。
    • 使用 AOF 优缺点:参考 http://redis.cn/topics/persistence.html
    • redis-check-aof 命令修复损坏的 aof 文件。
    • redis-check-dump 命令修复损坏的 dump 文件。
  8. 两种持久化方式的选择
    • 只把 redis 当做缓存,不使用;
    • 追求恢复速度,使用 rdb;
    • 追求丢失数据量较少,采用 aof;
    • 两者都要,两者都使用,但机器性能要好。
  9. 强调使用 rdb 或 aof 来实现持久化,而不是主要用来做备份。

六、redis 的事务处理

  1. redis 事务与关系型事务的主要区别:
    • 关系型的事务具有 ACID 属性,redis 不具有。
    • 关系型的事务内部处理过程很复杂,redis 相对简单。
    • 关系型的事务可以回滚,redis 不可以。
  2. redis 事务用到的命令:
    • multi 表示事务的开始;
    • discard 取消事务,也就是当前的事务不再执行;
    • exec 执行事务;
    • watch 观察指定的 key 在执行期间是否被改变;
  3. 事务的具体用法:
    • 事务可以由多个命令组成,所有的命令按照顺序执行。
    • multi 表示事务开始的一个位置,从此位置开始所有的命令都属于事务中的命令,直到遇到 exec 才开始执行,或者遇到 discard 事务就取消。
    • 执行 multi 命令会创建一个命令队列,所有后续
    • 执行事务的五种情形:
      • A 事务正常进行,在所有的命令都入队后执行 exec 命令,执行过程中每个命令都返回了 OK。
      • B 事务被取消,在中途执行了 discard 命令,让本次事务不再执行。
      • C 全体连坐,当其中的一条命令出错,所有的命令都不会执行。
      • D 独自承受,如果多条命令中有一些出现了数据类型的错误,这些命令不会执行,其余正确的命令正常执行。
      • E watch,监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

七、redis 的复制

  • 复制在 redis 中用 replication 来表示,这里的复制包括缓存中和持久化后的数据的复制。
  • 理解什么是 redis 的主从复制:
    1. 分布式的含义,在不同的主机上运行的是不同的服务。
    2. 集群的含义,在不同的主机上运行的是相同的服务或数据
    3. redis 主从复制的目的有两个:实现读写分离,主服务器用作写,从服务器用作读,因此必须保证主服务器的数据变化必须复制到从服务器,这种结构就是集群,可以令系统具有高性能的特点;实现容灾备份,当某台服务器挂掉后,另一台可以继续工作,保证系统的可用性。因此在生产环境下,实现 redis 的主从复制是完全有必要的。
  • 如何实现主从复制
    1. 一主多从:一台 master 主机,至少两台以上的 slave 从机。
      • info replication 查看状态
      • slaveof host port 从机连接主机
      • slaveof no one 取消连接主机
    2. redis 的哨兵
      • 它是基于主从架构下发展出来的一种自动化的集群检测功能。
      • 它本身也是一个 redis 的实例,它的启动与启动 redis 实例是一样的。
      • 针对每个哨兵都要提供配置文件,文件名必须是 sentinel.conf,该文件中必须指定需要监控的主机,同时还需要确定一个参数,该参数是一个选举参数(投票数量),该数量是感知到被监控的主机挂了的其它机器的数量。
  • 基于 redis 的分区来实现高可用的集群
    1. 集群中至少有三台主机,每台主机存放部分数据,所有主机共同分担数据的存储;
    2. 每台主机都有属于它的从机,以分担查询的工作量,当主机挂了,哨后可以让从机成为主机,此时会有延迟,但它只是局部的而不是整体的。
    3. redis 设计了一种数据存放的逻辑结构,也就是 slot(槽),每个槽是一个独立的存储数据的空间。规定总共有 16384 个槽,每台主机平均分配这些槽。当新增数据时,由集群的管理者决定数据放在哪台主机上,它基于一种算法,取 key 的 hash,用该 hash 对 16384 进行模运算,结果就是槽的序号,这样数据就会在槽中均匀分布。
    4. 对每台主机都配上从机,可以是一对多,当单台主机挂掉后,从机可以升级为主机,保证集群的工作状态是稳定的。
    5. 主机挂了,从机自动成为主机,主机恢复后成为从机。在本节点(包括主机和从机)上执行 keys * ,查到的是本节点上所有的 key,其他节点上的 key 查不到但是可以获取地址。
    6. 集群失效(fail)的条件
      • 如果一个节点只有主机没有从机,该节点挂了则整个集群失效。
      • 如果所有的主机都有从机,任何节点的失效要通过所有的主机投票产生,如果多数主机投出的票指定某个主机失效,该主机就失效,从机就会成为主机。投票的原则就是向其它的所有主机发出 oing,如果规定的时间未收到回应,对应的主机会被投出失效票。
      • 基于以上的方式,每台主机都会被其他的主机投票,也会投其他主机的票,因此任何两台主机之间都是连通的。
    7. 使用集群的限制
      • 不支持所有的集合操作,比如交、并、差。
      • 不支持使用了多个 key 的命令,比如 mset、mget 等。
      • 如果其他的主机都认为某台主机失效,可这时客户端正在向该主机发出命令,这份数据会丢失。
      • 只能使用 0 号数据库。
    8. 相关命令:
      • cluster info 查看集群信息
      • cluster nodes 查看当前节点信息

猜你喜欢

转载自blog.csdn.net/qq_44628734/article/details/121053170