Redis系列笔记第二篇----Redis高级

Redis笔记第二篇—Redis高级

本文目录

  • Redis笔记第二篇---Redis高级
    • 1. Linux环境的Redis安装
      • 1.1 从Redis源码编译安装
      • 1.2 从指定端口号启动
      • 1.3 从配置文件启动
    • 2. Redis持久化
      • 2.1 什么是持久化
      • 2.2 RDB
        • 2.2.1 save
        • 2.2.2 bgsave
        • 2.2.3 自动执行的保存
        • 2.2.4 两种保存方式对比
        • 2.2.5 RDB的特殊启动形式
        • 2.2.6 RDB的优缺点
      • 2.3 AOF
        • 2.3.1 AOF写数据的过程
        • 2.3.2 AOF重写
    • 3. Redis事务
      • 3.1 事务简介
      • 3.2 事务基本操作
        • 3.2.1 基本命令
        • 3.2.2 事务的工作流程
        • 3.2.3 事务的注意事项
      • 3.3 锁
      • 3.4 分布式锁
      • 3.5 分布式锁的客户端问题
    • 4. Redis删除策略
      • 4.1 数据删除策略
        • 4.1.1 定时删除
        • 4.1.2 惰性删除
        • 4.1.3 定期删除
      • 4.3 数据逐出算法
    • 5. redis.conf
    • 6. Redis高级数据类型
      • 6.1 Bitmaps
        • 6.1.1 基本操作
        • 6.1.2 扩展操作
      • 6.2 HyperLogLog
      • 6.3 GEO

Redis学习系列第二篇笔记,将学习Redis持久化、Redis事务、Redis删除策略、Redis配置文件以及高级数据类型。

1. Linux环境的Redis安装

1.1 从Redis源码编译安装

$tar -xvf redis-VERSION.tar.gz

$cd redis-VERSION

$make install

1.2 从指定端口号启动

#服务端从6380端口启动
$redis-server --port 6380

#客户端从6380端口连接
$redis-cli -p 6380

1.3 从配置文件启动

配置文件如下:

  • bind 127.0.0.1
  • port 6379
  • daemonize yes 按照守护进程方式启动
  • logfile "6379.log" 日志文件的存储路径
  • dir ./ 上面的文件存储在哪儿

从配置文件启动:

$redis-server redis.conf

如果想启动多个Redis服务,只需稍微修改下配置文件即可。

2. Redis持久化

2.1 什么是持久化

  • 比如意外断电。

利用永久性介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制叫做持久化。

为了防止数据丢失。

数据持久化的两种形式:

  • 保存数据(快照)----RDB
  • 保存操作过程(日志)----AOF

2.2 RDB

2.2.1 save

手动执行save指令,会立即生成dump.rdb文件。


rdb相关配置

  • dbfilename dump.rdb 一般设置为dump-端口号.rdb,方便查看。
  • dir 存储rdb文件的路径。
  • rdbcompression yes 默认会压缩数据。
  • rdbchecksum yes 默认会开启,数据校验,防止数据出错。

save指令工作原理

save指令会阻塞服务器,有可能造成长时间阻塞。不建议线上环境使用。

2.2.2 bgsave

后台会在某个时间执行保存操作。

执行过程:

客户端发送bgsave指令,服务端返回给客户端Background saving started消息,同时调用fork函数生成一个子进程来创建rdb文件。

注意:
bgsave命令对save的阻塞进行了优化,Redis内部所有涉及到RDB的操作都采用了bgsave的方式。

  • stop-writes-on-bgsave-error yes 后台存储时如果出现了错误,是否停止保存。默认是yes。

2.2.3 自动执行的保存

在conf文件内进行配置。

save seconds changes

  • 满足特定时间内key的变化数量时即执行save操作。

2.2.4 两种保存方式对比

方式 save bgsave
读写 同步 异步
是否阻塞服务端
额外内存
启动新进程

2.2.5 RDB的特殊启动形式

  1. 全量复制
    • 主从复制中详细讲解。
  2. 服务器运行过程中重启
    • debug reload
  3. 关闭服务器时指定保存数据
    • shutdown save

2.2.6 RDB的优缺点

优点:

  • 内部是压缩的二进制文件,存储效率高。
  • 存储的是某个时间点的快照,适合进行数据备份。
  • 恢复数据比AOF快得多。
  • 应用于每隔x小时进行一次备份,用于灾备。

缺点:

  • 无法实时持久化,有丢失数据的可能。
  • bgsave会牺牲性能。
  • 可能多个版本的Redis之间不兼容。

2.3 AOF

AOF, append only file, 目前是Redis实时持久化的主流方式。

  • 记录操作过程。

2.3.1 AOF写数据的过程

AOF写数据的三种策略:

  • always 每次,数据零误差,性能较低。不建议使用。
  • everysec 每秒,每秒将缓冲区的命令同步到AOF文件内,可能会丢失一秒的数据。Redis默认。
  • no 系统控制,过程不可控。

在conf文件中启用AOF:

# 开启AOF, 默认是no
appendonly yes|no

# 配置AOF写数据策略
appendfsync always|everysec|no

# 配置AOF文件名
appendfilename filename

2.3.2 AOF重写

  • 降低磁盘占用量
  • 降低恢复时的数据量,提高恢复成功率。

重写规则:

  1. 进程内超时的数据不再写入。
  2. 忽略无效指令,set name 1, set name 2,只保留最后一条。
  3. 合并数据,lpush a 1, lpush a 2, 合并为lpush a 1 2。每条指令最多64个元素。

重写命令

手动重写:

bgrewriteaof

自动重写:

3. Redis事务

3.1 事务简介

Redis事务就是一个命令执行的队列,将一系列预定义的命令包装成一个整体。当执行时,一次性按照顺序执行,中间不会被打断。

3.2 事务基本操作

3.2.1 基本命令

事务的边界:

开头:multi, 结尾:exec

取消事务:discard

3.2.2 事务的工作流程

3.2.3 事务的注意事项

  1. 如果输入的命令格式错误了怎么办?

如果有错误的指令,那么所有的操作都会被清除。

  1. 如果事务执行过程中出错了怎么办?

正确的命令会执行,错误的指令不会执行。

已经执行完毕的命令对应的数据不会自动回滚。

3.3 锁

基于特定条件的事务执行----锁。

对key添加监视锁,在exec之前如果key发生了变化,则不执行。

  • watch key1 [key2...]
  • unwatch 取消对所有key的监视。

注意:事务中不能watch。

3.4 分布式锁

如何避免最后一件商品被多个人买到?

分布式锁,类似于Java的同步代码块。

  • 使用setnx设置一个公共锁

    setnx lock-key value

    有值则返回失败,没有值则返回设置成功。

    可以理解为厕所钥匙。

    操作完毕后通过del删除锁。

3.5 分布式锁的客户端问题

如果客户端拿到分布式锁后客户端宕机了怎么办?

给锁设置时效性。

  • expire lock-key second
  • pexpire lock-key 毫秒

4. Redis删除策略

已经过期的数据真的被删除了吗?

Redis数据有三种状态:

  • XX:具有时效性的数据。
  • -1:永久有效的数据。
  • -2:过期的数据。

set和get的优先级比较高,del优先级低。过期的数据不一定被立刻删除,可能还会留一段时间。

4.1 数据删除策略

Redis内部会有一个expires空间,里面是[数据的内存地址-过期时间]的形式。

删除策略:在CPU和内存之间找一个平衡。

4.1.1 定时删除

key的过期时间到了后定时器立刻去删除数据。

  • 优点:省内存。
  • 缺点:CPU压力大。

4.1.2 惰性删除

数据到期后不做处理,如果过期后有人访问这个数据,发现过期了,删除,返回不存在。

  • 优点:省CPU。
  • 缺点:费内存。

4.1.3 定期删除

启动时,将server.hz设置为10,每秒钟执行hz次serverCron()->databaseCron()->activeExpireCycle()。

activeExpireCycle()对每个expire空间逐一进行检测,每次执行(250/hz) ms

随机挑w个key进行检测,如果key超时,就删除。如果删除的量超过了w的25%,那么就会接着执行这个过程。

参数current_db用以记录activeExpireCycle()执行到了哪个db。

w取值由配置文件决定。ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP

4.3 数据逐出算法

如果数据进入Redis时内存不够了怎么办?

临时删除一些数据,称为数据逐出/淘汰,这个策略称为逐出算法。

逐出算法可能会失败,如果失败了,会报错。

影响逐出算法的配置:

  • maxmemory

    • 最大可用内存,默认是0,表示不受限制,一般设为50%以上。
  • maxmemory-samples
    每次选取待删除数据的个数。

  • maxmemory-policy

    • 逐出策略。
  1. 检查易失数据。(在expires里面删除数据)

    • volatile-lru 最近使用时间离得最远的数据。(Recently)(早期Redis默认操作)
    • volatile-lfu 最近使用次数最少。 (Frequently)
    • volatile-ttl 挑选即将过期的数据。
    • volatile-random 任意选择。
  2. 检测全库数据(在dict中删除数据)

    • allkeys-lru
    • allkeys-lfu
    • allkeys-random
  3. 放弃数据逐出(Redis4.0开始的默认操作)

    • no-enviction 禁止取出数据,可能会Out Of Memory。

配置文件:maxmemory-policy 逐出策略

注意:

查看INFO信息中的命中缓存次数及未命中次数,根据这个信息来调优。

5. redis.conf

服务器基础配置

  • 设置服务器以守护进程的方式运行

    daemonize yes|no

  • 绑定主机地址(使之只能让这个地址来访问)

    bind 127.0.0.1

  • 设置端口

    port 6379

  • 设置数据库数量

    databases 16

日志配置

  • 指定日志级别

    loglevel debug|verbose|notice|warning

  • 日志记录文件名

    logfile 端口号.log

服务端对客户端的配置

  • 设定同一时间内最大客户端连接数,0代表无限制。

    maxclients 0

  • 客户端闲置最大时长,0代表不关闭。

    timeout 300

多服务器快捷配置

  • 导入并加载指定位置的配置文件,用于快捷创建Redis公共配置较多的Redis实例配置文件。

    include /path/某个端口号.conf

6. Redis高级数据类型

高级数据类型更倾向于解决一种问题,应用面比较狭窄。

6.1 Bitmaps

6.1.1 基本操作

  • 获取指定key上对应偏移量上的bit值

    getbit key offset

  • 设定指定key上对应偏移量的值

    setbit key offset value

6.1.2 扩展操作

  • 统计指定key中1的个数

    bitcount key [start end]

  • 对指定的key进行位运算

    bitop op destKey key1 [key2 key3...]

    • destKey 是目标key,结果存进这个key里。

    • op有四种,交并非异或。

      • and 交(&&)

      • or 并 (||)

      • not 非 (!)

      • xor 异或 (^)

6.2 HyperLogLog

比如统计UV独立用户,HyperLogLog应用面更窄,用来做基数统计。

内部用了LogLog算法。

  • 添加数据

    pfadd key value1 [value2 value3...]

  • 统计数据

    pfcount key1 [key2 key3...]

  • 合并数据

    pfmerge destKey key1 [key2 key3...]

注意:

  • 不存储数据,只记录数量。
  • 数量是估算的,不保证精确。误差接近0.81%。
  • 占用空间极小。使用最多12KB的内存。
  • 合并后占用的就是12K,不管合并前这几个key占用多大。

6.3 GEO

求两个点的距离(关联关系)。

  • 添加坐标点

    geoadd key 横坐标1 纵坐标1 value1 [横坐标2 纵坐标2 value2 ...]

  • 取出来坐标

    geopos key value

  • 计算距离

    geodist key value1 value2 [m/km/ft/mi]

    • 后面四个是单位。ft和mi分别是英尺和英里。
    • 这是计算地球上两个坐标的。
    • 横纵坐标就是经纬度。
  • 根据坐标求范围内的数据

    georadius key 经度 维度 半径 m/km/ft/mi [WITHCOORD WITHDIST WITHHASH] [COUNT count]

    • WITHCOORD 结果带坐标
    • WITHDIST 结果带距离
    • WITHHASH 结果带哈希
    • COUNT count 只展示最近的count个
  • 根据点求范围内数据

    geiradiusbymember key value 半径 单位 [后面的同上]

  • 求坐标哈希值

    geohash key value1 [value2...]

你可能感兴趣的:(Redis,Redis)