1.介绍

Redis是一款开源的、高性能的键-值存储。它常被称作是一款数据结构服务器。Redis的键值可以包括字符串(strings)类型,同时它还包括哈希(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等数据类型。 对于这些数据类型可以执行原子操作。

为了获得优异的性能,Redis采用了内存中数据集的方式。同时,Redis支持数据的持久化,可以每隔一段时间将数据集转存到磁盘上,或者在日志尾部追加每一条操作命令(append only file,aof)。

Redis同样支持主从复制,并且具有非常快速的非阻塞首次同步、网络断开自动重连等功能。同时Redis还具有其它一些特性,其中包括简单的事物支持、发布订阅 ( pub/sub)、管道(pipeline)和虚拟内存(vm)等  。

2.安装

若要启用 systemd,使用 wsl.conf 通过管理员权限在文本编辑器中打开,并将以下行添加到 /etc/wsl.conf,然后从 PowerShell 使用 wsl.exe --shutdown 来关闭以便重启,重启后,使用 systemctl list-unit-files --type=service 命令确认。

    [boot]

    systemd=true

    sudo apt update
    sudo apt install redis-server -y   # 安装 redis
    redis-server --version             # 检查安装是否成功
    redis-cli --version

    sudo service redis-server start    # SysVinit 服务管理,启动 Redis 服务
    sudo systemctl start redis-server  # systemd 服务管理,WSL2 未启用 systemd,无法使用 systemctl 命令
    redis-server                       # 进程级,前台运行
    sudo redis-server /etc/redis/redis.conf --daemonize yes # 进程级,以守护进程方式启动

    sudo service  redis-server status  # 检查服务状态
    redis-cli ping                     # 测试连接
    sudo service  redis-server stop    # 停止 Redis 服务

3.配置

对/etc/redis/redis.conf修改:

3.1 守护进程

Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
    daemonize no

3.2 pid 文件

当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
    pidfile /var/run/redis.pid

3.3 监听端口

指定Redis监听端口,默认端口为6379
    port 6379

3.4 主机地址

绑定的主机地址
    bind 127.0.0.1

3.5 客户端闲置关闭时间

当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
    timeout 300

3.6 日志记录级别

Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
    loglevel verbose

3.7 日志记录方式

默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
    logfile stdout

3.8 数据库的数量

默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id
    databases 16

3.9 数据同步

指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
    save <seconds> <changes>
    Redis默认配置文件中提供了三个条件:
    save 900 1
    save 300 10
    save 60 10000
    分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。清空save则不会保存到rdb文件

3.10 是否压缩数据

指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
    rdbcompression yes

3.11 本地数据库文件名

默认值为dump.rdb
    dbfilename dump.rdb

3.12 本地数据库存放目录

     dir ./

3.13 slave设置

设置当本机为slave服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
    slaveof <masterip> <masterport>

3.14 连接到master的密码

当master服务设置了密码保护时,slav服务连接master的密码
    masterauth <master-password>

3.15 Redis连接密码

如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
    requirepass foobared

3.16 同一时间最大客户端连接数

默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
    maxclients 128

3.17 最大内存限制

Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
    maxmemory <bytes>

3.18 日志记录

指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis 本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
    appendonly no

3.19 日志文件名

指定更新日志文件名,默认为appendonly.aof
     appendfilename appendonly.aof

3.20 更新日志条件

共有3个可选值:no:表示等操作系统进行数据缓存同步到磁盘(快) ;always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全); everysec:表示每秒同步一次(折衷,默认值)
    appendfsync everysec

3.21 启用虚拟内存

默认值为no,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中
     vm-enabled no

3.22 虚拟内存文件路径

默认值为/tmp/redis.swap,不可多个Redis实例共享
     vm-swap-file /tmp/redis.swap

3.23 vm-max-memory

将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0
     vm-max-memory 0

3.24 vm-page-size

Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值
     vm-page-size 32

3.25 设置swap文件中的page数量

由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。
     vm-pages 134217728

3.26 设置访问swap文件的线程数

最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4
     vm-max-threads 4

3.27 客户端应答包合并

设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启
    glueoutputbuf yes

3.28 哈希

 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法
    hash-max-zipmap-entries 64
    hash-max-zipmap-value 512

3.29 重置哈希

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

3.30 指定包含其它的配置文件

可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
    include /path/to/local.conf

4.支持的数据类型

Redis是一个key-value的数据库,key一般是String类型,格式设置为:

[项目名]:[业务名]:[类型]:[id]。

不过value的类型多种多样:

  • String: hello world
    • 包含:字符串、int、float
    • - SET:添加或者修改已经存在的一个String类型的键值对
      - GET:根据key获取String类型的value
      - MSET:批量添加多个String类型的键值对
      - MGET:根据多个key获取多个String类型的value
      - INCR:让一个整型的key自增1
      - INCRBY: 让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2
      - INCRBYFLOAT:让一个浮点类型的数字自增并指定步长
      - SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行
      - SETEX:添加一个String类型的键值对,并且指定有效期
  • Hash: {name: "Jack", age: 21}
    • - HSET key field value:添加或者修改hash类型key的field的值
      - HGET key field:获取一个hash类型key的field的值
      - HMSET:批量添加多个hash类型key的field的值
      - HMGET:批量获取多个hash类型key的field的值
      - HGETALL:获取一个hash类型的key中的所有的field和value
      - HKEYS:获取一个hash类型的key中的所有的field
      - HVALS:获取一个hash类型的key中的所有的value
      - HINCRBY: 让一个hash类型key的字段值自增并指定步长
      - HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行
  • List: [A -> B -> C -> C]
    • - LPUSH key element ... :向列表左侧插入一个或多个元素
      - LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
      - RPUSH key element ... :向列表右侧插入一个或多个元素
      - RPOP key:移除并返回列表右侧的第一个元素
      - LRANGE key star end:返回一段角标范围内的所有元素
      - BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil
  • Set: {A, B, C}
    • - SADD key member ... :向set中添加一个或多个元素
      - SREM key member ... : 移除set中的指定元素
      - SCARD key:返回set中元素的个数
      - SISMEMBER key member: 判断一个元素是否存在于set中
      - SMEMBERS:获取set中的所有元素
      - SINTER key1 key2 ... :求key1与key2的交集
      - SDIFF key1 key2 ... :求key1与key2的差集
      - SUNION key1 key2 ..:求key1和key2的并集
  • SortedSet: {A: 1, B: 2, C: 3}
    • SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。SortedSet具备下列特性:

      • 可排序、元素不重复、查询速度快
      • 因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。

    • - ZADD key score member:添加一个或多个元素到sorted set,如果已经存在则更新其score值
      - ZREM key member:删除sorted set中的一个指定元素
      - ZSCORE key member:获取sorted set中的指定元素的score值
      - ZRANK key member:获取sorted set 中的指定元素的排名
      - ZCARD key:获取sorted set中的元素个数
      - ZCOUNT key min max:统计score值在给定范围内的所有元素的个数
      - ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment值
      - ZRANGE key min max:按照score排序后,获取指定排名范围内的元素
      - ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
      - ZDIFF、ZINTER、ZUNION:求差集、交集、并集

  • GEO: {A: (120.3, 30.5)}
  • BitMap: 0110110101110101011
  • HyperLog: 0110110101110101011

5.持久化

redis是支持持久化的内存数据库,即redis需要经常将内存中的数据同步到磁盘来保证持久化,这是相对memcache来说的一个大的优势。redis支持两种持久化方式,一种是 Snapshotting(快照)也是默认方式,另一种是Append-only file(缩写aof)的方式。 

Snapshotting:快照是默认的持久化方式。这种方式将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以配置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,默认的快照保存配置:save 900 1  #900秒内如果超过1个key被修改,则发起快照保存;save 300 10 #300秒内容如超过10个key被修改,则发起快照保存;save 60 10000

Append-only file:aof 比快照方式有更好的持久化性,是由于在使用aof持久化方式时,redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)。当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当然由于os会在内核中缓存 write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。不过我们可以通过配置文件告诉redis我们想要 通过fsync函数强制os写入到磁盘的时机。

方式如下(默认是:每秒fsync一次)

  • appendonly yes            //启用aof持久化方式
  • appendfsync always     //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
  • appendfsync everysec  //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
  • appendfsync no            //完全依赖os,性能最好,持久化没保证

6.主从复制

主从复制允许多个slave server拥有和master server相同的数据库副本,特点:

  • 1.master可以有多个slave
  • 2.除了多个slave连到相同的master外,slave也可以连接其他slave形成图状结构
  • 3.主从复制不会阻塞master。也就是说当一个或多个slave与master进行初次同步数据时,master可以继续处理client发来的请求。相反slave在初次同步数据时则会阻塞,不能处理client的请求。
  • 4.主从复制可以用来提高系统的可伸缩性(可以用多个slave 专门用于client的读请求,比如sort操作可以使用slave来处理),也可以用来做简单的数据冗余。
  • 5.可以在master禁用数据持久化,只需要注释掉master 配置文件中的所有save配置,然后只在slave上配置数据持久化。

7.事务

  • Multi          事物开始
  • Exec          执行事务
  • Discard      放弃事务
  • Watch        监听key
  • Unwatch    放弃所有key的监听

如:

  • WATCH balance           # 监视 key "balance"
  • MULTI
  • DECRBY balance 100  # 扣100
  • INCR total_orders        # 订单+1
  • EXEC                           # 提交

如果在 WATCH 之后、EXEC 之前,别的客户端修改了 balance,那么 EXEC 会失败(返回 nil),扣款操作不会执行。

Redis 对事务的支持相对简单,它不提供传统数据库的 ACID 特性,但能保证一个客户端发起的事务中所有命令在 EXEC 时原子性、顺序执行,期间不会被其他客户端命令打断。

使用 WATCH 命令可以监视指定 key,若在事务执行前这些 key 被其他客户端修改,则整个事务将失败(返回 nil),以此实现乐观锁机制。

WATCH 监听和事务状态均绑定当前连接,连接断开后自动清除。

注意:Redis 事务不支持回滚,也不保证隔离性 —— 其他客户端仍可并发修改数据,因此依赖 WATCH 检测冲突。

8.发布订阅

发布订阅(pub/sub)是一种消息通信模式。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将消息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的消息时。订阅该消息类型的全部client都会收到此消息。这里消息的传递是多对多的。一个client可以订阅多个 channel,也可以向多个channel发送消息。

  • Subscribe
  • Unsubscribe
  • Psubscribe
  • Punsubscribe
  • Publish

9.管道

redis是一个cs模式的tcp server,使用和http类似的请求响应协议。一个client可以通过一个socket连接发起多个请求命令。每个请求命令发出后client通常 会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client。基本的通信过程如下:
Client: INCR X
Server: 1
Client:
INCR X
Server: 2
Client:
INCR X
Server: 3
Client:
INCR X
Server: 4

基本上四个命令需要8个tcp报文才能完成。由于通信会有网络延迟,假如从client和server之间的包传输时间需要0.125秒。那么上面的四个命令8个报文至少会需要1秒才能完成。

利用pipeline的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端。通信过程如下:
Client: INCR X
Client:
INCR X
Client:
INCR X
Client:
INCR X
Server: 1
Server: 2
Server: 3
Server: 4
 

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐