Redis学习笔记

2021/5/6 2:27:19

本文主要是介绍Redis学习笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、NoSQL

1. 关系型数据库的发展历程

(1) 单机MySQL的美好年代

img

应用程序通过数据访问层(DAL)使用数据库

问题:

  • 数据总量太大,一个机器放不下
  • 数据索引一个机器内存放不下
  • 访问量(读写混合)一个实例不能承受

(2) Memcached(缓存)+MySQL+垂直拆分

img

把常用数据放入缓存中, 并对数据库进行垂直拆分,即按照业务将表进行分类,分布到不同的数据库上面,减轻访问压力

问题:读写集中在一个数据库上让数据库不堪重负

(3) MySQL主从读写分离

img

从库是主库的镜像,主数据库负责写,从数据库负责读

问题:在高并发下会出现严重的锁问题

(4) 分表分库+水平拆分+MySQL集群

img

对数据库的表进行水平拆分,即把一张表的不同部分存放到不同数据库中,并布置到集群中

分布式:不同的多台服务器上部署不同的服务模块

集群:不同的多台服务器上部署相同的服务模块

(5) MySQL的发展瓶颈

经常存储一些大文本字段,导致数据库表非常的大,在做数据库恢复的时候就导致非常的慢。 MySQL的扩展性差(需要复杂的技术来实现),大数据下IO压力大,表结构更改困难 。

2. NoSQL数据库简介

(1) 简介

如果要对用户数据进行挖掘,则SQL数据库已经不适合这些应用了,所以使用NoSQL数据库。NoSQL=Not Only SQL,泛指非关系型数据库。这些类型的数据存储不需要固定的模式,无需多余的操作就可以横向扩展。NoSQL数据库的一个共同特点就是去掉关系型数据库的关系型特性,数据之间无关系,这样就容易拓展。NoSQL无需实现为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系型数据库中增删字段是一件非常麻烦的事情。

(2) NoSQL特点

  • 不仅仅是SQL
  • 没有声明型查询语言
  • 没有预定义的模式
  • 键-值对存储,列存储,文档存储,图像数据库
  • 最终一致性,而非ACID属性
  • 非结构化和不可预知的数据
  • CAP定理
  • 高性能,高可用性和可伸缩性

(3) 3V+3高

3V

  • 海量Volume
  • 多样Variety
  • 实时Velocity

3高

  • 高并发

  • 高可扩

  • 高性能

3. NoSQL数据模型简介

(1) 聚合模型

  • KV键值对
  • BSON:类似于JSON
  • 列族: 按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一 列或者某几列的查询有非常大的IO优势。
  • 图形:类似于知识图谱

(2) NoSQL数据库的四大分类

  • KV键值,如Redis
  • 文档型数据库(BSON格式比较多),如MongoDB
  • 列存储数据库,如HBase
  • 图关系数据库,如Neo4J

(3) 分布式数据库CAP原理

  • Consistency(强一致性)
  • Availability(高可用性)
  • Partition tolerance(分区容错性)
img

CAP理论就是说在分布式存储系统中,最多只能实现上面的两点

  • CA:单点集群,满足一致性、可用性的系统,通常在可扩展性上不太强大
  • CP:满足一致性、分区容错性的系统,通常性能不是特别高
  • AP:满足可用性、分区容错性的系统,通常可能对一致性的要求低一些

分布式系统中分区容错性P是必须要有的,所以在强一致性C和高可用性A中选择

  • CA:传统关系型数据库

  • AP:大多数网站架构的选择

  • CP:Redis、MongoDB

(4) BASE

为了解决关系型数据库强一致性引起的问题而引起的可用性降低而提出的解决方案

  • 基本可用(Basically Available)
  • 软状态(Soft state)
  • 最终一致(Eventually consistent)

其思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上的改观。

二、Redis入门

1. 入门概述

(1) 简介

Redis:REmote Dictionary Server(远程字典服务器)。是开源的,用C语言编写的,遵守BSD协议,是一个高性能的(key-value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库。

(2) 特点

与其他key-value的NoSQL数据库相比,Redis有三个特点:

  • 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
  • 不仅仅支持简单的key-value类型的数据,还提供了list、set、zset、hash等数据结构的存储
  • 支持数据的备份,即master-slave模式的数据备份

(3) Redis能做什么

  • 内存存储和持久化:支持异步将内存中的数据写到硬盘上,同时不影响继续服务
  • 取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的list集合中
  • 模拟类似于HttpSession这种需要设定过期时间的功能
  • 发布、订阅消息系统
  • 定时器、计数器

2. 下载和安装

(1) 下载

Redis中文官网

Redis官网

(2) 安装(Linux系统下)

下载安装包安装

  • 下载获得redis-x.x.x.tar.gz后放入/opt目录下
  • 使用tar -zxvf redis-x.x.x.tar.gz进行解压,解压后出现文件夹redis-x.x.x
  • 进入目录redis-x.x.x
  • 执行make命令(需要安装gcc)
    • 若已经安装了gcc还是make失败,报缺少Jemalloc/jemalloc.h,则运行make distclean后再make
  • make完成后继续执行make install命令
  • 默认安装目录:/usr/local/bin

安装时碰到两个问题,一个是redis.conf文件没权限,用chmod 777 redis.conf命令更改权限即可,另一个是缺少日志文件,解决办法是在相应的路径下创建对应的日志文件,并更改其权限即可。注意执行命令时可能需要使用root权限。


使用命令安装(推荐使用)

sudo apt-get update
sudo apt-get install redis-server

此时的redis配置文件目录为/etc/redis/redis.conf

(3) 启动Redis

  • /etc/redis/redis-x.x.x目录下执行redis-server redis.conf,使用不同的配置文件时,启动起来的redis是不同的
  • 执行redis-cli -p 6379启动Redis客户端
  • 在客户端输入set hello world,再输入get hello得到hello对应的值world
  • 在命令行输入ps -ef|grep redis查看是否启动成功
  • 输入exit退出

(4) 基础知识和命令

  • Redis中默认有16个数据库,默认使用0号库
  • 通过select <dbid>切换数据库,如select 5
  • DBSIZE查看key的个数,Redis下支持Tab键自动补全,keys *查看所有的key
  • FLUSHDB删除当前库,FLUSHALL删除所有库
  • 统一密码管理:16个库都是同样的密码
  • Redis索引都是从0开始
  • 默认端口是6379

三、Redis的使用

1. key关键字

(1) 常用

  • keys *:查看所有键
  • exists key:判断某个key是否存在
  • move key 数据库名:把key剪切到指定数据库
  • expire key 时间:为key设定过期时间,单位是秒,过期后key被删除
  • ttl key:查看还有多少秒过期,-1表示永不过期,-2表示已过期(不存在)
  • type key:查看key的类型

(2) 不常用

  • dump key:序列化给定key,并返回被序列化的值
  • expireat key 时间戳:和expire租用类似,都是为key设置过期时间,不同的是参数为Unix时间戳
  • expire key 毫秒:设置key过期的时间,以毫秒为单位
  • expireat key 毫秒时间戳:设置key过期的时间戳,以毫秒为单位
  • keys 模式:查找所有符合给定模式的key,所谓模式就是正则表达式
  • persist key:移除key的过期时间,key将持久保持
  • pttl key:以毫秒为单位返回key的剩余过期时间
  • randomkey:从当前数据库随机返回一个key
  • rename key 新键名:修改key的名称
  • renamenx key 新键名:仅当新键名不存在时,将key修改为新键名

2. Redis的五大数据类型简介

(1) 字符串(String)

与Memcached一样的类型,一个key对应一个value。是二进制安全的,意思是string可以包含任何数据。字符串value最多可以是512M

(2) 哈希(Hash)

一个键值对集合,其键是string类型,其值是一个键值对,类似于java中的Map<String, Object>,特别适合用于存储对象

(3) 列表(List)

是简单的字符串列表,底层实际是个链表,按照插入顺序排序,可以添加一个元素到列表的头部或尾部。如果键不存在会创建新链表,反之新增内容。如果值全移除,对应的键也就消失了。

(4) 集合(Set)

是string的无序集合,通过HashTable实现的

(5) 有序集合(ZSet)

与Set不同的是每个元素都会关联一个double类型的分数。redis正是通过分数䣂为集合中的元素进行从小到大的排序,zset的元素是唯一的,但分数是可以重复的

3. 字符串(String)

(1) 常用

  • set key value:设置指定字符串的值

  • get key:获取指定字符串的值

  • del key:删除字符串

  • append key value:如果key已经存在并且是一个字符串,append命令将给定的值追加到字符串原来值的末尾

  • strlen key:返回key所存储的字符串值的长度


  • incr key:将key中存储的数字值增加1

  • incrby key 增量值:将key所存储的值加上给定的增量值(一定是数字)

  • decr key:将key中存储的数字值减1

  • decrby key 减量值:将key所存储的值减去给定的减量值(一定是数字)


  • getrange key 起始值 终止值:返回key中字符串值的子字符,0到-1表示全部

  • setrange key 偏移量 value:用给定的值覆盖给定key所储存的字符串值,从偏移量开始


  • setex key 时间 value:(set with expire),将值关联到key,并设置key的过期时间,以秒为单位

  • setnx key value:(set if not exist),只有在key不存在时设置key的值


  • mset key1 value1 [key2 value2...]:同时设置一个或多个键值对

  • mget key1 [key2...]:获取所有(一个或多个)给定key的值

  • msetnx key1 value1 [key2 value2...]:同时设置一个或多个键值对,当且仅当所有给定的key都不存在


  • getset key value:将给定的key的值设为给定的值,并返回key的旧值

(2) 不常用

  • getbit key 偏移量:对key所储存的字符串值,获取指定偏移量上的位(bit)
  • setbit key 偏移量 value:对key所储存的字符串值,设置或清除指定偏移量上的位
  • psetex key 毫秒 value:与setex命令类似,但以毫秒为单位设置key的生存时间
  • incrbyfloat key 增量值:将key所存储的值加上给定的浮点数增量值

4. 哈希(Hash)

(1) 常用

  • hset key 字段 value:将哈希表中的字段值设为给定值

  • hget key 字段:获取存储在哈希表中指定字段的值

  • hmset key 字段1 value1 [字段2 value2...]:同时将多个字段-值对设置到哈希表中

  • hmget key 字段1 [字段2...]:获取所有给定的字段的值

  • hgetall key:获取哈希表中所有的字段和值

  • hdel key 字段1 [字段2...]:删除一个或多个哈希表字段


  • hlen key:获取哈希表中字段的数量


  • hexists key 字段:查看哈希表中指定字段是否存在


  • hkeys key:获取哈希表中的所有字段

  • hvals key:获取哈希表中的所有值


  • hincrby key 字段 增量值:为哈希表的指定字段的整数值加上增量值

  • hincrbyfloat key 字段 增量值:为哈希表的指定字段的浮点数数值加上增量值


  • hsetnx key 字段 value:只有在字段不存在时,才设置哈希表的字段值

(2) 不常用

  • hscan key 游标 [MATCH patter] [COUNT count]:迭代哈希表中的键值对

5. 列表(List)

(1) 常用

  • lpush key value1 [value2...]:将一个或多个值插入到列表头部

  • rpush key value1 [value2...]:在列表中添加一个或多个值

  • lrange key 起始值 终止值:获取列表下标在指定范围内的元素,lrange key 0 -1查看全部元素


  • lpop key:移除并获取列表的第一个元素

  • rpop key:移除并获取列表最后一个元素


  • lindex key 索引值:通过索引获取列表中的元素


  • llen key:获取列表长度


  • lrem key 个数 value:移除指定个数个指定值的列表元素


  • ltrim key 起始值 终止值:对一个列表进行修剪,即让列表只保留下标在指定区间内的元素,其他的删除


  • rpoplpush 源列表 目的列表:移除列表的最后一个元素,并将该元素添加到另一个列表,并返回该值


  • lset key 索引 value:通过索引设置列表元素的值


  • linsert key before|after 目标值 插入值:在列表的元素前或后插入元素,若存在多个同值元素,则只在第一个后面插入

(2) 不常用

  • blpop key1 [key2] 超时值:移除并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
  • brpop key1 [key2] 超时值:移除并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
  • brpoplpush 源列表 目的列表 超时值:从列表中弹出一个值,将弹出的元素插入到另一个列表中并返回它,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
  • lpushx key value:将一个或多个值插入到已存在的列表头部
  • rpushx key value:为已存在的列表添加值

6. 集合(Set)

(1) 常用

  • sadd key 元素1 [元素2...]:向集合添加一个或多个元素,返回成功添加的元素个数

  • smembers key:返回集合中的所有元素

  • sismember key 元素:判断元素是否在集合的元素


  • scard key:获取集合的元素数


  • srem key 元素1 [元素2...]:移除集合中一个或多个元素,返回成功移除的个数


  • srandmember key [个数]:随机返回集合中指定个数个元素


  • spop key:移除并返回集合中的一个随机元素


  • smove 源集合 目的集合 元素:将元素从源集合移动到目的集合


  • sdiff key1 [key2]:返回给定所有集合的差集,在第一个集合中,但不在后面的任何一个集合中

  • sinter key1 [key2...]:返回给定所有集合的交集

  • sunion key1 [key2...]:返回所有给定集合的并集

(2) 不常用

  • sdiffstore 目的集合 key1 [key2...]:返回给定所有集合的差集并存储在目标集合中
  • sinterstore 目的集合 key1 [key2]:返回给定所有集合的交集并存储在目标集合中
  • sunionstore 目的集合 key1 [key2]:所有给定结合的并集存储在目的集合中
  • sscan key 游标 [MATCH pattern] [COUNT count]:迭代集合中的元素

7. 有序集合(ZSet)

(1) 常用

  • zadd key 分数1 元素1 [分数2 元素2]:向有序集合中添加一个或多个元素,或者更新已存在的元素的分数

  • zrange key 起始值 终止值 [WITHSCORES]:通过索引区间返回有序集合中指定区间内的元素,带withscores时也显示分数


  • zrangebyscore key 最小值 最大值 [WITHSCORES] [LIMIT]:通过分数区间返回有序集合指定区间内的元素。区间默认前闭后闭,最小值和最大值前可以加括号(表示不包含该数字,limit的作用是返回限制,类似于分页,如limit 2 3即从下标为2的开始截取3个返回


  • zrem key 元素 [元素...]:移除集合中的一个或多个元素


  • zcard key:获取有序集合的元素数

  • zcount key 最小值 最大值:计算在有序集合中指定区间分数的元素数,最小值和最大值前可以加括号(表示不包含该数字

  • zrank key 元素:返回有序集合中指定元素按分数升序排序后的索引

  • zscore key 元素:返回有序集合中指定元素的分数值


  • zrevrank key 元素:返回有序集合中指定元素按分数降序排序后的索引


  • zrevrange key 起始值 终止值 [WITHSCORES]:先按分数降序排序,然后取指定下标区间的元素


  • zrevrangebyscore key 最大值 最小值 [WITHSCORES]:先按分数降序排序,然后取指定分数区间内的元素

(2) 不常用

  • zincrby key 增量值 元素:有序集合中对指定元素的分数加上增量值
  • zinterstore 目的有序集合 numkeys key [键...]:计算给定的一个或多个有序集合的交集并将结果存储在新的有序集合中
  • zlexcount key 最小值 最大值:在有序集合中数计算指定字典区间内元素数量
  • zrangebylex key 最小值 最大值 [LIMIT 偏移量 个数]:通过字典区间返回有序集合的元素
  • zremrangebylex key 最小值 最大值:移除有序集合中给定的字典区间的所有元素
  • zremrangebyrank key 起始值 终止值:移除有序集合中给定的排名区间的所有元素
  • zremrangebyscore key 最小值 最大值:移除有序集合中给定的分数区间的所有元素
  • zunionstore 目标有序集合 numkeys key1 [key2...]:计算给定的一个或多个有序集合的并集,那个存储在新的key中
  • zscan key 游标 [MATCH pattern] [COUNT count]:迭代有序集合中的元素(包括元素和元素的分数)

8. Redis配置文件

Redis的配置文件redis.conf位于目录/etc/redis下,配置文件中大小写不敏感,且1k和1kb是不一样的

Redis可以通过config get 配置设置名config set 配置设置名来获取和设置配置文件中某选项的值

(1) includes包含

通过include包含其他的配置文件,如include /path/to/other.conf

(2) general通用

  • daemonize yes:以守护进程的方式运行,默认为no
  • pidfile /var/run/redis.pid : 当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入/var/run/redis.pid文件,可以通过pidfile指定
  • tcp-backlog 511 :设置tcp的backlog,backlog其实是一个链接队列,backlog队列总和=未完成三次握手队列+已经完成三次握手队列。在高并发环境下需要一个高backlog值来避免客户端连接的问题
  • port 6379: 指定 Redis 监听端口
  • timeout 300: 当客户端闲置多长秒后关闭连接,如果指定为 0 ,表示关闭该功能
  • bind 127.0.0.1:绑定的主机的地址,可绑定多个
  • tcp-keepalive 0:单位为秒,如果设置为0,则不会进行Keepalive检测,建议设为60秒
  • loglevel notice: 指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warning,默认为 notice
  • logfile stdout: 日志记录方式,默认为标准输出,如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
  • Syslog-enabled no:是否打开系统日志
  • Syslog-ident redis:指定系统日志标识
  • Syslog-facility local0:指定syslog设备,值可以是user或local0~local7
  • databases 16: 设置数据库的数量

(3) snapshotting快照

  • save <seconds> <changes>: 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合。默认配置文件中提供了3个条件,有一个满足即可触发。也可以用save命令手动备份
    • save 900 1: 900 秒(15 分钟)内有 1 个更改
    • save 300 10: 300 秒(5 分钟)内有 10 个更改
    • save 60 10000: 60 秒内有 10000 个更改
  • Stop-writes-on-bgsave-error yes:当后台保存发生错误时停止写入。如果设为no,则表示不在乎数据不一致或有其他的手段发现和控制
  • rdbcompression yes: 指定存储至本地数据库时是否压缩数据,默认为 yes, 可以关闭该选项,但会导致数据库文件变的巨大
  • rdbchecksum yes:在存储快照后,可以让redis使用CRC64算法来进行数据校验,但会增加10%的性能消耗
  • dbfilename dump.rdb: 指定本地数据库文件名
  • dir ./: 指定本地数据库存放目录

(4) replication复制

  • slaveof <masterid> <masterport>: 置当本机为 slave 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步
  • masterauth <master-password>: 当 master 服务设置了密码保护时,slave服务连接 master 的密码

(5) security安全

  • requriepass <password>: 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 auth 命令提供密码,默认关闭

(6) limits限制

  • maxclients 128: 设置同一时间最大客户端连接数, 0表示不作限制
  • maxmemory <bytes>: 指定 Redis 最大内存限制, 达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key

(7) append only mode追加

  • appendonly no: 指定是否在每次更新操作后进行日志记录,Redis 在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。 默认为 no
  • appendfilename appendonly.aof: 指定更新日志文件名
  • appendfsync everysec: 指定更新日志条件,有3个可选值
    • no:表示等操作系统进行数据缓存同步到磁盘(快)
    • always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全)
    • everysec:表示每秒同步一次(折中,默认值)
  • No-appendfsync-on-rewrite:重写时是否可以运用Appendfsync,用默认no即可,保证数据安全性
  • auto-aof-rewrite-percentage 100:设置重写的基准值,当AOF文件为上次重写时AOF文件的一倍是才重写
  • auto-aof-rewrite-min-size 64mb:设置重写的基准值,当AOF文件超过64MB时才会重写

(8) advanced config

  • activerehashing yes: 指定是否激活重置哈希,默认为开启

(9) 其他

以下是在自己的redis.conf文件中没有找到,但是在其他参考资料中提到的配置选项

  • vm-enabled no: 指定是否启用虚拟内存机制,默认值为 no, VM 机制将数据分页存放,由 Redis 将访问量较少的页即冷数据 swap 到磁盘上,访问多的页面由磁盘自动换出到内存中
  • vm-swap-file /tmp/redis.swap: 虚拟内存文件路径, 不可多个 Redis 实例共享
  • vm-max-memory 0: 将所有大于 vm-max-memory 的数据存入虚拟内存
  • vm-page-size 32: Redis swap 文件分成了很多的 page,一个对象可以保存在多个 page 上面,但一个 page 上不能被多个对象共享,vm-page-size 是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page 大小最好设置为 32 或者 64byte
  • vm-pages 134217728: 设置 swap 文件中的 page 数量
  • vm-max-threads 4: 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟
  • glueoutputbuf yes: 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启
  • hash-max-zipmap-entries 64 : 指定在超过一定的数量时,采用一种特殊的哈希算法
  • hash-max-zipmap-value 512:指定最大的元素超过某一临界值时,采用一种特殊的哈希算法

config get requirepass:获取密码

config set requirepass "123":将密码设置为123

auth 123:使用如ping命令之间需要先登录

9. 持久化之RDB

(1) 简介

RDB(Redis DataBase):在指定的时间间隔内将内存中的数据集快照写入磁盘, 恢复时将快照文件直接读到内存里。

Redis会单独创建(fork)一个子进程进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中主进程不进行任何IO操作,这就确保了极高的性能。

如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后数据可能丢失。

(2) fork

fork的作用是复制一个与当前进程一样的进程,新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一样,但是是一个全新的进程,并作为原进程的子进程。

(3) 如何触发RDB快照

  • 配置文件中的快照snapshotting配置
  • save或bgsave命令手动保存
    • save:只管保存,其他不管,全部阻塞
    • bgsave:Redis会在后台一部进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间
  • 执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义

(4) 如何恢复

  • 将备份文件dump.rdb移动到redis安装目录并启动服务器即可
  • redis-check-rdb --fix dump.rdb命令用来修复dump.rdb文件

(5) 如何停止

动态所有停止RDB保存规则的方法:redis-cli config set save "",或者在配置文件中将save设为空

(6) 优劣

优势: 适合大规模的数据恢复,对数据完整性和一致性要求不高

劣势:在一定时间间隔做一次备份,所有如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。fork的时候,内存中的数据被克隆了一份,大致2北大的膨胀性需要考虑。

10. 持久化之AOF

(1) 简介

AOF(Append Only File):以日志的形式来记录每个写操作,将Redis执行过的所有写智力高记录下来(读操作不记录),只许追加文件但不可以更改文件,Redis启动之初会读取该文件重构数据,换言之,Redis重启的话就根据日志文件价格写指令从前到后执行一次以完成数据的恢复工作

appendonly.aof和dump.rdb可以共存,但先加载前者,当前者不存在或有问题时再加载后者。建议RDB和AOF两种同时开启

(2) AOF启动和恢复

  • 正常恢复
    • 启动:在配置文件的``append only mode中修改配置,将默认的appendonly no`改为yes
    • 恢复:重启redis,自动重新加载
  • 异常恢复
    • 启动:修改默认的appendonly no,改为yes
    • 修复:redis-check-aof --fix appendonly.aof命令用来修复appendonly.aof文件
    • 恢复:重启redis,自动重新加载

(3) rewrite:

AOF采用文件追加方式,文件会越来越大,为避免出现这种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof进行重写

(4) 重写原理:

AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中的数据,每条记录有一条的set语句。重写AOF文件的操作,并没有读取旧的AOF文件,而是将整个内存中国的数据库内容用命令的方式重写了一个新的AOF文件,这点和快照有些类似。

(5) 触发机制:

Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次重写后大小的一倍且文件大约64MB时触发。

(6) 优劣

优势:可以每秒同步、每修改同步和不同步。

劣势:相同数据集的数据而言AOF文件会远大于RDB文件,恢复速度慢于RDB。AOF运行效率要慢于RDB,每秒同步策略效率较好,不同步效率和RDB相同。

11. Redis事务

(1) 事务

一次可以执行多个命令,本质是一组命令的集合,一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不允许加塞。

(2) 常用命令

  • discard:取消事务,放弃执行事务块内的所有命令

  • exec:执行所有事务块内的命令,在此之前只是入队但没执行

  • multi:标记一个事务块的开始,在此之后的命令只是入队但没执行

  • unwatch:取消watch命令对所有key的监视

  • watch key1 [key2...]:监视一个或多个key,如果在事务执行之前这些key被其他命令(非本事务的命令)所改动,那么事务将被打断。watch命令在multi命令之前,类似于乐观锁

(3) 四种情况

  • 正常执行:exec:执行所有事务块内的命令,在此之前只是入队但没执行

  • 放弃事务:discard:取消事务,放弃执行事务块内的所有命令

  • 全体连坐:如果中间有一条命令出错,则全部不执行。当在exec前就报error时会出现该情况

  • 冤头债主:如果中间有一条命令出错,只有出错的命令不执行。当在exec前没有报error时会出现该情况,如对一个字符串加1

(4) watch监控:

  • 乐观锁:每次去拿数据的时候都会认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制,提交版本必须大于当前记录版本才能执行更新。
  • 悲观锁:每次去拿数据的时候都会认为别人会修改,所以在每次拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。
  • CAS(Check And Set)

(5) 事务的3阶段

  • 开启:以multi开始一个事务
  • 入队:将多个事务入队到事务中,接到这些命令并不会立即执行,而是放到执行的事务队列里面
  • 执行:由exec命令触发执行事务

(6) 事务的3特性

  • 单独的隔离操作:事务中所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
  • 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交钱任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头疼的问题
  • 不保证原子性:Redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

12. Redis的发布和订阅

是进程间的一种消息通信模式,发送者(pub)发送消息,订阅者(sub)接受消息。

命令

  • psubscribe pattern1 [pattern2...]:订阅一个或多个符合给定模式的频道,模式类似于正则表达式
  • pubsub subcommand [argument1 [argument2...]]:查看订阅与发布系统状态
  • publish channel message:将消息发送到指定频道
  • punsubscribe [pattern1 [pattern2...]]:退订所有给定模式的频道
  • subscribe channel1 [channel2...]:订阅给定的一个或多个频道的信息
  • unsubscribe [channel1 [channel2...]]:退订给定的频道
subscribe c1 c2 c3
publish c2 hello-redis

13. Redis的主从复制

(1) 是什么

主机数据更新后根据配置和策略,自动同步到备机的master/slave机制,master以写为主,slave以读为主。主要用于读写分离和容灾恢复。

(2) 怎么玩

  • 配从(库)不配主(库)
  • 从库配置:slaveof 主库ip 主库端口
    • 每次与master断开后,都需要重新链接,除非你配置进redis.conf文件
    • Info replication
  • 修改配置文件细节操作
    • 拷贝多个redis.conf文件
    • 开启daemonize yes
    • pid文件名字
    • 指定端口
    • log文件名字
    • dump.rdb名字
  • 常用3招
    • 一主二仆:先用不同的配置文件在多个端口开多个Redis,此时每个Redis都是主机,在一个Redis上添加key,并在其他Redis上执行slaveof 主库ip 主库端口命令。此时从机和主机数据完全一样。可以用info replication命令查看当前Redis的属性,是从机还是主机。从机只能读不能写。当主机关机后,从机不会替代主机,还是从机。当主机恢复后,从机会自动和主机保持一致。从机关机后,再开机不会自动与主机连接,除非在配置文件中进行了相关配置。
    • 薪火相传:上一个从机可以是下一个从机的主机,从机同样可以接收其他从机的连接和同步请求,那么该从机作为了链条中下一个主机,可以有效减轻主机的写压力。中途变更转向:会清除之前的数据,重新建立拷贝最新的
    • 反客为主:当主机挂掉后从从机中选出一个作为主机,使用slaveof no one命令指定新的主机,并对其他从机重新绑定新的主机

(3) 复制原理

从机启动成功连接到主机后会发送一个sync命令。主机借到命令后启动后台的存盘进程,同时手机所有接受到的用于修改数据集命令,在后台进程执行完毕后,主机将传送整个文件到从机,以完成一次完全同步。全量复制:而从机服务在接收到数据库文件数据后,将其存盘并加载到内存中。增量复制:主机继续将新的所有收集到的修改命令依次传给从机,完成同步。但是只要是重新连接主机,一次完全同步(全量复制)将被自动执行

(4) 哨兵模式

反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转化为主库

  • 调整结构,6379带着6380和6381
  • 自定义的/myredis目录下新建sentinel.conf文件,文件名不能错
  • 配置哨兵,在sentinel.conf文件中填写内容
    • sentinel monitor 被监控数据库名(自己起名字) 127.0.0.1 6379 1
    • 上面最后一个数字1表示主机挂掉后从机投票产生替代的主机
  • 启动哨兵
    • redis-sentinel /myredis/sentinel.conf
    • 上述目录依照各自的实际情况配置,可能目录不同
  • 正常主从演示
  • 原有的主机挂了
  • 投票重选
  • 重新主从继续开工,info replication查看
  • 如果之前的主机回来了,会被哨兵监控到并转化为新主机的从机

(5) 复制的缺点

由于所有的写操作都是先在主机上操作,然后同步到从机上,所以从主机同步到从机有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,从机数量的增加也会使这个问题更加严重



这篇关于Redis学习笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程