Redis 是一款常用的 NoSQL 数据库。本文将 Redis 的相关内容进行整理,以供查缺补漏~

1. NoSQL

1.1 SQL 类型局限

SQL 类型局限性包括:

  • 数据总量大小可能超过机器容量。
  • 数据索引(B+ 树)可能超过机器内存容量。
  • 访问量(读写混合)可能超过一个实例容量。

SQL 发展过程:

  • 单机 MySQL。
  • Memcached 缓存 + MySQL + 垂直拆分。
    • Memcached 是独立的分布式缓存服务器,为多个 web 服务器提供共享的高性能缓存服务,后续又通过哈希算法解决多态缓存服务器扩展及数据安全一致性保证的问题。
  • MySQL 主从复制读写分离。
    • Memcached 仅能解决数据库读取压力,无法解决写入压力。通过主从复制技术,实现读写分离。代表是 MySQL 的主从模式 Master-Slave。
  • 分表分库 + 水平拆分 + MySQL 集群。
    • MySQL 主库的写压力增加,MyISAM 使用表锁,无法应对大规模高并发,逐渐被 InnoDB 引擎代替。同时,分表分库开始用于解决大规模读写问题。水平拆分就是将频繁写的数据拆分出来。MySQL Cluster 提供了更好的可靠性保证,但性能不能达到要求。

SQL 扩展瓶颈:

  • 存储一些大文本字段导致数据库特别大,数据恢复非常慢。
  • 扩展性差,表结构修改困难,需要复杂技术实现。
  • 不能很好应对所有场景。
  • 大数据情况下读写压力大。

随着社交网络、地理位置、用户数据和用户操作日志成倍增加,SQL 数据库已经不再适合这些应用了。NoSQL 却能很好处理这种问题。

1.2 NoSQL 定义

NoSQL 定义:

  • NoSQL = Not Only SQL,泛指非关系型数据库。
  • 传统关系数据库在应对 web2.0 网站,特别是超大规模和高并发的 SNS 类型的 web2.0 纯动态网站已经力不从心。
  • NoSQL 就是用来解决大规模数据集合、多重数据种类带来的挑战,尤其是大数据应用难题。

NoSQL 特点:

  • 易扩展:去掉了关系数据库的关系型特性,从而有利于扩展。
  • 大数据高性能:同样是无关系性,大大提高了读写性能。MySQL 采用的 Query Cache 无法应对频繁更新,NoSQL 的 Cache 则是记录级的,能方便应对大规模读写。
  • 多样灵活的数据模型:NoSQL 不用为要存储的数据建立字段,可以随时存储自定义数据格式。MySQL 为大规模数据增加一个字段则极其麻烦。

传统 RDBMS 和 NoSQL 差别:

  • RDBMS:
    • 高度组织化结构化数据。
    • 结构化查询语言 SQL。
    • 数据和关系都存储在单独的表中。
    • 有数据操纵语言和数据定义语言。
    • 具有严格的一致性。
    • ACID 定理。
  • NoSQL:
    • 没有声明性查询语言。
    • 没有预定义模式。
    • 键值对存储,列存储,文档存储,图形存储。
    • 最终一致性,而没有 ACID 属性。
    • CAP 定理。
    • 高性能,高可用性,高可伸缩性。

1.3 NoSQL 应用

大数据、互联网时代需求特点:

  • 3V:
    • 海量 Volume。
    • 多样 Variety。
    • 实时 Velocity。
  • 3高:
    • 高并发。
    • 高可扩展性。
    • 高性能(高可用)。

Redis, Memcache, Mongodb 对比:

  • Redis:适合多种数据类型,效率高。
  • Memcache:如果单纯用于高速缓存,Memcache 效果最好。
  • Mongodb:最像 SQL 的 NoSQL。

Redis 内容:

  • KV
  • Cache
  • Persistence

应用方面的内容:

  • 当前情况下是 SQL 和 NoSQL 共同使用。
  • 商品包括:基本信息,商品属性,图片,相关关键字,热点高频信息,其他信息。
  • 基本信息:包括名称,商家,出厂日期,生产厂商等。
    • 因为变化较少,趋冷,所以存放在 SQL 中。
    • 阿里巴巴去 IOE 化:IBM 小型机,Oracle 数据库,EMC 存储设备。
  • 商品属性:包括商品描述,详情,评价等。一般是文字类。
    • 一般存放在 Mongodb 中。
  • 商品图片:
    • 一般存放在分布式文件系统中。例如:淘宝 TFS,Google GFS,Hadoop HDFS。
  • 商品关键字:
    • 一般用 ElasticSearch。
  • 商品高频信息:
    • 一般用 Tair, Redis, Memcache。
  • 其他信息:包括商品交易,价格计算,积分积累等。
    • 一般用外部接口。
  • 应用难点:数据的海量、多样、实时。数据源多样性和频繁变化重构。
  • 解决方法:添加一层统一数据平台服务层 EAI。
    • 例如:阿里巴巴的 UDSL。
    • 方法:映射,API,热点缓存......

如何设计关系型数据库和菲关系型数据库?以一个电商案例为例,包含电商客户、订单、订购、地址模型等为例:

  • 关系型数据库:设计 ER 图完成设计。1:1,1:N,N:N,主外键等内容。

  • image-20210120153309497

  • 非关系型数据库:使用 BSON 完成设计。

  • BSON:Binary Json,一种类似 json 的二进制形式的存储格式。和 json 一样支持内嵌的文档对象和数组对象。

  • { 
      "customer":{   
          "id":1136,   
          "name":"Z3",   
          "billingAddress":[{"city":"beijing"}],   
          "orders":[    
          {      
                  "id":17,      
                  "customerId":1136,      
                  "orderItems":[{"productId":27,"price":77.5,"productName":"thinking in java"}],      
                  "shippingAddress":[{"city":"beijing"}]      
                  "orderPayment":[{"ccinfo":"111-222-333","txnid":"asdfadcd334","billingAddress":{"city":"beijing"}}],      
          }    
      ]  
      }
    }
  • BSON 可以很方便的进行合并和分离,以及进行字符串操作。

  • 高并发操作最好不要使用关联查询。分布式事务不支持太多并发。使用 NoSQL 可以很方便地查询。

1.4 NoSQL 数据类型

NoSQL 数据类型:聚合模型。包括四种内容:KV 键值对,BSON,列族和图形。

  • KV 键值对。
  • BSON。
  • 列族:按列存储数据,方便存储结构化和半结构化数据,方便进行数据压缩,对于针对某列或某几列的查询有很大的优势。
  • image-20210120160518331
  • 图形。
  • image-20210120160821619

NOSQL 数据库类型包括四种类型:KV 键值,文档型数据库(BSON 格式),列存储数据库,图关系数据库。对应四种数据类型。

  • KV 键值:新浪 BerkeleyDB + Redis,美团 Redis + Tair,阿里百度 Memcache + Redis。
  • 文档型数据库:CouchDB,MongoDB。MongoDB 是一个基于分布式文件存储的数据库,用 C++ 编写,为 Web 应用提供可扩展的高性能存储。是一个介于关系型和非关系型的产品,是非关系型中功能最丰富的,最像关系型的。
  • 列存储数据库:Cassandra,HBase。HBase 和 Hadoop 是一套。
  • 图关系数据库:Neo4j,InfoGrid。存储关系内容。
  • image-20210120162141203

1.5 NoSQL CAP 原理

传统 ACID 内容:A 原子性,C 一致性,I 独立性,D 持久性。独立性就是 A 给 B 转 100 元,没转到 B 看不到。

CAP 原则内容:

  • Consistency:强一致性。
  • Availability:可用性。
  • Partition tolerance:分区容错性。

其中,由于分布式存储系统存在延迟、丢包现象,CAP 只能同时满足两类。分别是:

  • CA:RDBMS。传统 Oracle 数据库。

  • CP:MongoDB,HBase,Redis。

  • AP:CouchDB。

  • 在当前情况下,P 分区容错性是必须满足的。而 C 强一致性在目前已经不是必须的了,更重要的是 A 可用性。所以目前大部分是 AP。

  • 同时,现在很少用多个大表的关联查询了,更多的是单表的主键查询,以及单表的简单条件分页查询。SQL 功能被极大弱化了。

BASE 解决方案内容:

  • BASE 是为了解决关系数据库强一致性造成的可用性降低的解决方案。
  • Basically Available:基本可用。
  • Soft state:软状态。
  • Eventually consistent:最终一致。
  • 思想是,让系统某一时刻放松对一致性的要求,换取整体性能和可扩展性的改善。

分布式和集群内容:

  • 分布式:不同的多台服务器上部署不同的服务模块或工程。通过 Rpc/Rmi 通信和调用。
  • 集群:不同的多台服务器上部署相同的服务模块或工程。通过分布式调度软件进行统一调度。

2. Redis 基础

2.1 Redis 概念

Redis:REmote DIctionary Server 远程字典服务器。

  • 完全开源免费的,C 语言编写的,高性能的 KV 分布式内存数据库。
  • 基于内存运行,支持持久化的 NoSQL 数据库。
  • 支持数据持久化。将内存数据存到硬盘中。
  • 不仅仅简单支持 KV 类型数据,还支持 List, Set, Zset, Hash 等数据结构的存储。
  • 支持数据备份,即 Master-Slave 模式的数据备份。

Redis 特点:

  • 支持异步存储内存数据到硬盘上,同时不影响继续工作。
  • 支持取最新的 N 个数据的操作。
  • 支持设置过期时间等功能。
  • 支持发布、订阅消息系统。
  • 支持定时器、计数器。

Redis 相关内容:

  • 数据类型、基本操作及配置。
  • 持久化和复制,RDB/AOF。
  • 事务的控制(弱功能)。
  • 复制。
TIP:
并发:多个事件同一时间段发生。类似只有一个 CPU。
并行:多个事件同一时间发生。类似有多个 CPU。

串行:按顺序执行。
同步:等待方法返回。
异步:不等待方法返回。

2.2 Redis 配置

首先需要下载 gcc。gcc 是一款编译程序,支持 C, C++, Objective-C, Fortran, Java 和 Ada 等程序设计语言。

下载 Redis,解压后,进入目录输入 make 安装,随后进入 /src 输入 make install 测试。

image-20210121193002858

修改 redis.conf 将里面的 daemonize no 改成 yes,从而让服务器在后台启动。

启动服务器,进行连通测试。查看 redis 后台进程。

ps -ef | grep redis

连接 redis 服务器进行操作。需要进入 /usr/local/bin 中执行。

redis-server /bluestragglers/redis.conf
redis-cli -p 6379

ping #测试
PONG

set k1 HelloWorld
get k1

SHUTDOWN #断开连接
exit #退出客户端

2.3 Redis 基础命令

Redis 基础命令包括:

  • redis-server redis.conf位置:启动 Redis 服务器。
  • redis-cli [OPTION]:启动 Redis 客户端操作入口。
    • -p:指定端口,一般为 6379。
  • redis-benchmark:性能测试。需要先连接才能测试。
  • redis-check-aof:修复有问题的 AOF 文件。
  • redis-check-dump:修复有问题的 dump.rdb 文件。
  • redis-sentinel:redis 集群。
  • info replication:查看当前主机相关信息。
  • ping:测试。
  • SHUTDOWN:断开连接。
  • exit:退出客户端。

2.4 Redis 其他知识

Redis 其他内容包括:

  • Redis 单进程理解:Redis 采用单进程模型来处理客户端的请求。对读写事件的响应,是通过对 epoll 函数的包装来实现的,实际效率完全依赖于主进程执行效率。epoll 是 Linux 内核为处理大批量文件描述符而改进的 epoll,是 Linux 下多路复用 IO 接口 select/poll 的增强版本。能显著提高程序在大量并发连接中只有少量活跃下的系统 CPU 利用率。

  • Redis 数据库:默认有16个,可以通过 select 命令切换数据库。

  • Redis 常用命令:

    • select 数字:切换数据库。
    • dbsize:查看当前数据库的 key 数量。
    • flushdb:清空当前库。
    • flushall:清空所有库。
    • keys *:显示所有键。
  • flushselect 1 //切换到第2个数据
  • image-20210124155232208

3. Redis 数据类型

Redis 主要包括五大数据类型,分别是:

  • String:最基本的数据类型,可以理解为和 Memcached 一样的类型,KV。
    • string 类型二进制安全,也就是 string 可以包含任何数据,比如 jpg 图片或者序列化的对象。value 最大可以达到 512M。
    • 二进制安全:可以包含任何数据。
  • Hash:适合存储对象,类似 Java 的 Map。
  • List:简单的字符串列表,按照插入的顺序排序,可以头插和尾插,底层是链表。
  • Set:字符串无序集合,底层是 HashTable。
  • Zset:是有序集合,即 sorted set。每个元素都会关联一个 double 类型的分数,根据它进行由小到大排序。zset 成员唯一,但分数可以重复。

3.1 Redis Key 常用操作

Redis Key 常用的操作包括:

  • keys *:
  • exists 键值名字:
  • move 键值名字 数据库名:
  • expire 键值名字 秒钟:给键值设定过期时间。
  • ttl 键值名字:查看键值还有多少秒过期。
    • 返回 -1 表示永不过期,-2 表示已经过期。
    • 过期后就从内存删除了,内存中无法查到对应键。
  • type 键值名字:查看键值类型。

3.2 Redis String 常用操作

Redis String 的 KV 是 1:1 的。

Redis String 常用操作包括:

  • set
  • get
  • del
  • append
  • strlen
  • incr, decr:数字加减 1。
  • incrby, decyby:数字加减 N。
    • 格式是 incrby/decyby Key N。
  • getrange:获取指定区间值。
    • 格式是 getrange Key Left Right。
  • setrange:设置指定区间值。
    • 格式是 setrange Key Value。
  • setex:设置带过期时间的 key。
  • setnx:只有 key 不存在时设置 key。
  • mset:同时设置一个或多个 KV。
  • mget:同时获取一个或多个 KV。
  • msetnx:只有 key 不存在时设置一个或多个 KV。
  • getset:先 get 再 set。先获取旧值,再修改成新值,最后返回旧值。

3.3 Redis Hash 常用操作

Redis Hash 的 KV 是 1:1 的,但 V 也是一个 KV。

Redis Hash 常用操作包括:

  • hset
  • hget
  • hdel
  • hmset
  • hmget
  • hgetall
  • hlen
  • hexists:查看指定 Key1 中是否有指定 Key2.
    • 格式是:hexists Key1 Key2。
  • hkeys:获取 K。
  • hvals:获取 V。
  • hincrby, hincrbyfloat:数字加减 N。float 就是可以加减小数。
  • hsetnx:只有 key 不存在时设置 key。

3.4 Redis List 常用操作

Redis List 的 KV 是 1:N 的。

Redis List 很容易弄混的是,命令经常以 L 开头,但 L 有时候是指“左边”,有时候单纯是“List”。

Redis List 头插和尾插性能很高,中间操作一般。如果键不存在,创建新链表。如果值全移除,键也消失。

Redis List 常用操作包括:

  • lpush

  • rpush

  • lpop

  • rpop

  • llen

  • lset:修改指定 Key 的指定序号 Index 的值。

    • 格式是 lset Key Index Value。
  • linsert:在指定 Key 的已有值 Value1 的前面或后面加入新值 Value2。

    • 格式是 linsert Key before/after Value1 Value2。
  • lrange:获取指定 Key 对应的指定区域内的多个元素值。

    • 格式是 lrange Key Left Right。
    • Right 和 Python 差不多,-1 指的是最后一个元素。
  • lindex:获取指定 Key 对应的指定位置 Index 的元素值。

    • 格式是 lindex Key Index。
  • lrem:删除指定 Key1 中的 N 个 Key2 对应的值。

    • 格式是 lrem Key1 N Key2。

    • 例如:

    • RPUSH list 1 1 1 2 3
      LREM list 2 1
      LRANGE list 0 -1
      1) 1
      2) 2
      3) 3
  • ltrim:截取指定 Key 中的部分值,覆盖原数组。

    • 格式是 ltrim Key Left Right。

    • 例如:

    • RPUSH list 1 2 3 4 5
      LTRIM list 1 3
      LRANGE list 0 -1
      1) 2
      2) 3
      3) 4
  • rpoplpush:移除指定 Key1 的最后一个元素,添加给指定 Key2 。

    • 格式是 rpoplpush Key1 Key2。
    • image-20210127101636605

3.5 Redis Set 常用操作

Redis Set 的 KV 是 1:N 的。

Redis Set 常用操作包括:

  • sadd
  • smembers:获取集合中所有元素。
  • sismember
  • scard:获取集合中元素个数。
  • srem:删除指定 Key 中元素。
  • srandmember:随机删除指定 Key 中 N 个元素。
    • 格式是 srandmember Key N。
    • 如果 N 是负数,表示取出 N 个数,可以有重复值。
  • spop:随机获取指定 Key 中的一个元素。
  • smove:将指定 Key1 中的指定元素 Value 移到指定 Key2 中。
    • 格式是 smove Key1 Key2 Value。
  • sdiff:求指定 Key1 和 Key2 的差集。
    • 结果是在指定 Key1 而不在指定 Key2 中的内容。
  • sinter:交集。
  • sunion:并集。

3.6 Redis Zset 常用操作

Redis Zset 和 Set 基本一致,区别是加入了一个 score 值,许多操作都要加入 score。

Redis Zset 常用操作包括:

  • zadd
    • 格式是 zset Key1 Score1 Value1 Key2 Score2 Value2...
  • zrange
    • withscore:带 score 显示。
  • zrangebyscore
    • withscore
    • (:不包含边界条件。例如 zrangebyscore zset01 60 (90 就是不包含90。
    • limit Left N:从 Left 开始截取 N 个作为返回。例如 zrangebyscore zset01 60 90 limit 2 2 就是从2开始,截取2个。
  • zrank:获取下标值。
    • 格式是 zrank Key Value。
  • zrevrank
  • zrevrange
  • zrevrangebyscore
    • 注意顺序是 Right Left。
  • zrem
  • zcard
  • zcount:计算指定 Score1 和 Score2 内有多少元素。
  • zscore:获取分数。
    • 格式是 zscore Key Value

4. Redis 配置 redis.conf

Redis 配置文件是重中之重。可以说,配置 redis.conf 是工作的重要部分。

Redis 配置文件的主要内容包括:

  • 地址:存放在 redis 文件内,但应该拷贝出来,每修改一次拷贝一份,以免出错。
  • 通用配置:General 通用, Security 安全, Limits 限制, 常用配置。
  • 其他模块配置:Units 单位, Includes 包含, Snapshotting 快照, Replication 复制, Append Only Mode 追加。
  • Units 单位:配置了一些基本单位,大小写不敏感,不支持 bit 操作。
  • Includes 包含:用于添加其他包。
  • General 通用:
    • daemonize: 后台运行,应该调整为 yes。
    • pidfile:进程管道 ID 路径。
    • port
    • tcp-backlog:tcp-backlog 设置 tcp 的 backlog,其中,backlog 是一个连接队列,包含未完成三次握手的队列和已经完成三次握手的度列。在高并发环境下,需要一个高 backlog 值来避免慢客户端的连接问题,所以要确认增大 somaxconn 和 tcp_max_syn_backlog 两个值来达到想要的效果。
    • timeout:无操作的关闭时间。
    • bind:绑定端口。
    • tcp-keepalive:是否进行 keepalive 检测,建议设置为60秒。
    • loglevel:日志级别,包括 debug, verbose, notice, warning,日志级别越来越高,打出的信息越来越少。可以根据业务诉求进行调整。
    • logfile:日志文件。
    • syslog-enabled:是否记录系统日志。
    • syslog-ident:系统日志标识。
    • syslog-facility:输出日志设备,LOCAL0-7。
    • databases:数据库数量,默认16。
  • Snapshotting 快照:
    • save:RDB 快照存储指令。格式是 save 秒钟 写操作次数。如果不想用,可以设置为空字符串。
    • stop-writes-on-bgsave-error:设置为 no 表示不关心数据一致。
    • rdbcompression:是否压缩 RDB。用 LZF 算法,但会消耗 CPU。
    • rdbchecksum:是否数据校验。用 CRC64 算法,但会提高 10% 性能消耗。
    • rdbfilename:RDB 文件名。
    • dir:目录。
  • Replication 复制
  • Security 安全:主要是访问密码的查看、设置和取消。
    • config set requirepass 密码字符串(带双引号):设置密码。注意字符串要加双引号。
    • auth 密码:输入密码。
  • Limits 限制:主要是各种限制。
    • Maxclient:Redis 可以与多少客户端连接。
    • Maxmemory
    • Maxmemory-policy:包括六种算法,用于设置超过内存后的策略。
    • volate-lru:用 LRU 算法移除 Key,但仅针对设置并达到了过期时间的键。
    • allkeys-lru:用 LRU 算法移除 Key。
    • volatile-random:随机移除 Key,但仅针对设置并达到了过期时间的键。
    • allkeys-random:随机移除 Key。
    • volatile-ttl:移除 TTL 最小的键,也就是最近要过期的键。
    • noeviction:不进行移除,仅返回错误信息。这条是默认的策略。
    • Maxmemory-samples:由于 policy 中的 LRU 和 TTL 算法都是估计值,所以可以在这里设置默认样本数量,Redis 会根据这个数量的样本执行 LRU 和 TTL 算法。
  • Append Only Mode 追加:
    • appendonly:是否开启 AOF。
    • appendfilename:AOF 文件名。
    • appendfsync:是否同步持久化,包括三种,always, everysec, no。
    • no-appendfsync-rewrite:重写时是否同步持久化。默认 no 就可以,比较安全。
    • auto-aof-rewrite-min-size:重写基准值。
    • auto-aof-rewrite-percentage:重写基准值。

5. Redis 持久化

Redis 持久化核心内容:RDB 和 AOF。

5.1 RDB 持久化

RDB:Redis DataBase。

  • RDB 定义:RDB 是在指定时间内将内存中的数据集快照 snapshot 写入磁盘。恢复时,直接将快照读入内存中即可。
  • RDB 过程:Redis 会单独创建 fork 一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束了,再用这个临时文件替换上次持久化的文件。整个过程中,主进程不需要 IO 操作,从而确保了性能。如果需要大规模数据恢复,并且对完整性不是很敏感,那 RDB 方式会比 AOF 方式更加高效。RDB 的唯一缺点是数据可能丢失,破坏一些完整性。
  • RDB 过程的 fork 操作:复制一个与当前进程一样的进程,新进程的数据(变量、程序计数器等)与原进程一致,但是是一个全新进程,并作为原进程的子进程。
  • 存储文件:RDB 存储的是 dump.rdb 文件。
  • 如何触发 RDB 快照:包含三种方式:设置中配置,通过 save 或 bgsave 命令存储,以及通过 flushall 命令(但是这种仅仅是生成一个空的文件)。
    • save:存储。
    • bgsave: 后台异步存储。
  • 如何恢复:将备份文件 dump.rdb 文件移动到 Redis 安装目录并启动服务即可。可以通过config get dir 获取安装目录。如果不行,先备份,删除原 rdb,再将 rdb 放回去即可。
  • 如何停止:redis-cli config set save ""。
  • 优势:适合大规模数据恢复。
  • 劣势:默认隔一段时间存储一次快照;fork 时内存数据被克隆了一次,造成内存占用为2倍。

5.2 AOF 持久化

AOF:Append Only File。

  • AOF 定义:AOF 是以日志的形式记录每个写操作(不记录读操作),同时只允许追加文件而不允许改文件。
  • 存储文件:AOF 存储的是 appendonly.aof 文件。
    • 如何触发 AOF:包含三种方式:设置中配置,将 AOF 文件复制一份保存到对应目录,以及通过 redis-check-aof --fix 修复。
    • redis-check-aof --fix 用于修复写存在问题的 aof。
  • 如何启动:将 appendonly no 修改成 yes。
  • 如何恢复:重启 redis,重新加载。注意如果最后一行有 FLUSHALL 要删掉。
  • rewrite 操作:由于 AOF 采用的是文件追加方式,会导致文件越来越大,为了避免这种情况,引入了重写机制 rewrite。当 AOF 大小超过阈值时,Redis 就会压缩内容,只保留恢复数据的最小指令集。
    • 命令:bgrewriteaof。
    • 原理:引入新进程,遍历新进程内存的数据,每条数据用一个 set 命令,写入 AOF 文件,这样就不用重新读取以前的 AOF 文件了。rewrite 和快照有点类似。
    • 触发机制:Redis 记录每次重写时的 AOF 大小,当超过上次一倍且大于 64M 时触发。
  • 优势:三种同步方式:always, everysec, no。可以决定是否随时持久化到磁盘,以确保完整性。
  • 劣势:相同数据量,aof 文件远大于 rdb 文件,恢复速度也要慢一些。

5.3 总结

RDB 持久化能够在指定时间间隔内对数据快速持久化。

AOF 持久化能更好地保证数据一致性。

可以同时使用两种持久化方式,AOF 为主,RDB 用作备份。

6. Redis 事务

6.1 Redis 事务概念

Redis 事务就是一次性执行多个命令,是一组命令的集合。一个事物中的各个命令都会序列化,具有原子性。

Redis 事务的作用是构建命令序列,一次执行完成,按顺序执行,排他地执行命令。

6.2 Redis 事务常用命令

Redis 事务常用命令包括:

  • discard:取消事务,放弃执行事务内所有命令。
  • exec:执行事务。
  • multi:标记一个事务的开始。
  • watch:监视一个或多个 key。如果事务执行前 key 被改变,则停止执行事务。
  • unwatch:取消监视 key。
  • image-20210131144842750
  • Redis 包含两种报错,一种是编译时报错,一种是执行时报错。编译时报错会导致整个事务失败,而执行时出错其他没有出错的地方还是会执行。
  • image-20210131145401535
  • Watch 监控:包括三种类型:悲观锁,乐观锁,CAS (Check And Set)。Watch 指令类似乐观锁。
  • 乐观锁:不会上锁,但更新时会判断其他线程有没有对数据修改。会使用版本号策略或 CAS 算法实现。版本号策略就是更新版本号必须必原数据版本号大。操作失败则回滚。
  • CAS:多个线程更新一个数据时,只有一个成功,其他通知失败,但并不挂起,可以再次竞争。
  • 悲观锁:多个线程更新一个数据时,只有一个执行,其他全部挂起等待。应用有 MySQL 的读锁、写锁、行锁、表锁,Java 的 synchronized 关键字。
  • image-20210131150253847
  • Watch 命令类似乐观锁。事务执行时如果发现被更改,则事务不会被执行。

7. Redis 发布及订阅

7.1 Redis 发布及订阅概念

发布及订阅是进程间的一种消息通信模式,发送者 Pub 发布消息,订阅者 Sub 接收消息。

7.2 Redis 发布及订阅常用命令

Redis 发布及订阅常用命令包括:

  • psubscribe:订阅若干个符合要求的频道。
  • pubsub:查看订阅频道的状态。
  • publish:消息发送到指定频道。
  • punsubscribe:退订所有给定模式频道。
  • subscribe:订阅若干个频道。
  • unsubscribe:退订指定频道。

例如:

image-20210131193822689

8. Redis 复制

8.1 Redis 复制概念

Redis 也采用主从复制,读写分离的策略,类似于 MySQL。

主从复制:

  • 更新主机数据,同时自动同步到从机中。主机主要用于写,从机用于读。
  • 作用:读写分离,容灾恢复。

8.2 Redis 复制常用命令

配置方法:

  • 只需要配置从机,不需要配置主机。
  • slaveof 主机IP 主机端口:从机配置。
  • 每次主机断开后,都需要重新连接。除非在 redis.conf 中进行过配置。
  • 配置 redis.conf:设置 pidfile, log, dump.rdb。每个从机都需要一个 redis.conf 文件。
  • info replication:查看当前主机相关信息。

image-20210131202452323

相关问题:

  • 从机不能写,只能读主机的东西。
  • 反客为主:slaveof no one:从 slave 变成 master 了。
  • 连接主机后,就会将主机内容全部更新到从机。

哨兵模式:

  • 能够从后台监视主机是否故障。如果故障,自动将从机转为主机。
  • 配置方法:新建一个 sentinel.conf 文件,名字不能错。
  • 配置:sentinel monitor 被监控数据库名字 127.0.0.1 6379 1。
  • 数字 1 表示主机挂掉后,从机投票选择谁成为主机。
  • 启动哨兵:redis-sentinel 文件地址。
  • 从机转为主机后,主机如果回来,就会成为从机。

9. Redis Java 客户端 Jedis

参考内容

  1. 尚硅谷 Redis 教程