乐趣区

关于SegmentFault:⭐Redis-备忘录-基础

[TOC]

文档 / 链接

  • Redis 中文文档

    如同只到 3.* 版本

  • Redis 丑但更新的中文文档

图片来自: https://segmentfault.com/a/11…

高性能

官网数据: 10W+ QPS

  • 数据存储在内存
  • 单线程: 防止上下文切换和锁
  • 多路 I / O 复用

数据类型及利用场景

String 字符串

  • 单个 String 最大可存储 512 MB
  • 二进制平安.
  • 外部实现采纳 SDS(Simple Dynamic String)

    相似 Go 的切片, 通过额定调配空间防止频繁内存调配.

应用场景

  • 简略的 K-V 缓存性能
  • 计数器
  • 共享用户 Session
  • 分布式锁

    联合 lua

  • 限速器

    联合 lua

  • 并发控制器

    联合 lua

    比方管制热点行更新之类的, 可参考 Laravel 6.x 的 Illuminate\Redis\Limiters\ConcurrencyLimiter

Set 汇合

  • 无序汇合, 主动去重
  • 反对交加, 并集, 差集操作

应用场景

  • 排重
  • 独特 XX(独特好友 ….)

ZSet 有序汇合

应用场景

  • Top N 排行榜

    复合排序

List 列表

应用场景

  • New Top N
  • 音讯队列

    lpush, rbpop

    Laravel 的异步队列

    • Listqueues:default 期待执行的队列工作, rpush 和 lpop
    • Sorted Set queues:default:delayed 提早工作队列(包含失败重试)
    • Sorted Set queue:default:reserved 保留工作队列(执行中的队列, 防止脚本解体)

    取工作:

    1. queues:default 取出工作执行时会原子性地将其退出 queue:default:reserved 队列(score 为过期工夫), 同时减少其 attempts 次数.
    2. 工作执行结束, 移除 queue:default:reserved 中该工作. 若失败且失败次数未达到限度则插入到 queues:default:delayed 期待重试

Hash 哈希表

  • 适宜寄存相干的一组数据, 节俭内存占用.

HyperLogLog 基数统计

应用大量固定大小的内存 (12kb+) 来存储汇合中的惟一元素.

计数较小时采纳稠密矩阵, 较大时会主动转为浓密矩阵(此时占用 12KB), 标准误差: 0.81%

大数据量下的近似基数统计

若要齐全准确的, 则思考 set 或 bitmap

应用场景

  • UV 统计

    UV: 独立访客.

    可通过 PFMERGE 合并统计所有页面的 UV 统计

Bitmap 位图

其实也是 String, 反对按位操作.

应用场景

  • 节俭空间的统计

    准确的数量统计

  • 布隆过滤器

    反复断定.

    比方爬虫在对 URL 去重时, 数亿的 URL, 应用布隆过滤器能够大幅升高去重存储耗费, 代价仅仅是一小部分页面错过而已.

    垃圾邮件过滤性能.

Geo 地理位置

应用场景

  • 左近的人

Pub/Sub 公布订阅

应用场景

  • 音讯播送

    之前用 Go 写了一个短链接利用, 多个节点之间利用 redis 的公布订阅性能来异步移除已创立的短链在各个节点的本地缓存.

Stream

Redis 5.0 新增该类型: 长久化的公布 / 订阅零碎

集体临时理论去应用.

Stream 特点

  • 音讯 ack 后仅标记删除, 需自行管制最大音讯队列长度

    对于音讯量大且需长久保留, 还是倡议 Kafka

  • 反对消费者组(Consumer Group)

    保障每个音讯只会被消费者组内的其中一个消费者生产一次.

相干链接:

  • Redis(8)——公布 / 订阅与 Stream

CAS, Check And Set

了解为乐观锁

Check And Set, CAS 机制

CAS 是一种乐观锁机制

  1. WATCH 键

    此时能够读取键值, 若不合乎逻辑要求, 则可 UNWATCH 键, 并勾销后续操作

  2. MULTI 开启事务
  3. … 批改键值
  4. EXEC 执行事务

    此时若 watch 的键有任意一个在 WATCH 之后, EXEC 之前 值发生变化, 则事务勾销.

伪代码

WATCH mykey

val = GET mykey
if (val <= 0) {return;}

MULTI
INCRBY mykey -1
EXEC

若在 WATCH 之后, EXEC 之前, 其余客户端批改了键 mykey, 则以后客户端事务会被勾销. 此时须要做的就是一直反复下面步骤, 直到不满足条件 或 事务胜利.

题外话: 其实用 Lua 脚本来实现更给力, 如下:

eval 'if redis.call("get", KEYS[1]) >= ARGV[1] then redis.call("incrby", KEYS[1], -ARGV[1]) return 1 else return 0 end' 1 mykey 1

外部数据结构

sdshdr

struct sdshdr{
    int len;
    int free;
    char buf[];}

ziplist 和 quicklist

内存淘汰策略

Redis 在内存不足时的淘汰策略:

  1. volatile-lru: 从设置了过期工夫的数据集中,抉择最近最久未应用的数据开释
  2. allkeys-lru: 从数据集中(包含设置过期工夫以及未设置过期工夫的数据集中),抉择最近最久未应用的数据开释
  3. volatile-random: 从设置了过期工夫的数据集中,随机抉择一个数据进行开释
  4. allkeys-random: 从数据集中 (包含了设置过期工夫以及未设置过期工夫) 随机抉择一个数据进行入开释
  5. volatile-ttl:从设置了过期工夫的数据集中,抉择马上就要过期的数据进行开释操作
  6. noeviction(默认):返回谬误当内存限度达到并且客户端尝试执行会让更多内存被应用的命令(大部分的写入指令,但 DEL 和几个例外)

在 Redis 中 LRU 算法是一个近似 LRU 算法. 默认状况下,Redis 随机筛选 5 个键,并且从中选取一个最近最久未应用的 key 进行淘汰,在配置文件中能够通过 maxmemory-samples 的值来设置 redis 须要查看 key 的个数, 然而栓查的越多,消耗的工夫也就越久, 然而构造越准确(也就是 Redis 从内存中淘汰的对象未应用的工夫也就越久~).

Redis 3.0 在应用 10 个采样键时成果靠近原始 LRU 算法.

数据过期删除策略

个别的策略:

  • 定时删除:在设置键过期的工夫同时,创立一个定时器,让定时器在键过期工夫降临,立刻执行对键的删除操作。

    对 CPU 不敌对, 性能影响

  • 惰性删除: 放任键过期不论,然而每次从键空间获取键时,都会查看该键是否过期,如果过期的话,就删除该键。

    对内存不敌对

  • 定期删除: 每隔一段时间,程序都要对数据库进行一次查看,删除外面的过期键,至于要删除多少过期键,由算法而定。

Redis 的实现是 惰性删除 和 定期删除 同时应用.

长久化

参考

  • 面试中常常被问到的 Redis 长久化与复原

Redis 提供了两种长久化形式:

  1. RDB 长久化: 生成某个工夫点的快照文件
  2. AOF 长久化(append only file): 日志追加模式(Redis 协定格局保留)

Redis 能够同时应用以上两种长久化, 但在启动时会优先应用 AOF 文件复原.

Redis 4.0 之后存在一种新的长久化模式: 混合长久化

将 rdb 的文件和部分增量的 aof 文件相结合,rdb 能够应用相隔较长的工夫保留策略,aof 不须要是全量日志,只须要保留前一次 rdb 存储开始到这段时间增量 aof 日志即可,一般来说,这个日志量是十分小的.

RDB

RDB 长久化(快照)

  1. Redis 会 fork 一个子过程, 主过程持续解决申请.

    对于 fork: fork 的子过程占用内存大小等同于父过程, 实践须要 2 倍内存来实现长久化, 但 Linux 的 copy on write 机制能够让子过程共享父过程内存快照. 仅当父过程做内存批改操作时, 才会创立所批改内存页的正本.

  2. 子过程将内存中数据写入到一个紧凑的文件中

    它保留的是某个工夫点的残缺数据

备份策略

  • 能够对 rdb 文件备份, 比方保留最近 24 小时的每小时备份文件,每个月每天的备份文件,便于遇到问题时复原。
  • Redis 启动时会从 rdb 文件中复原数据到内存,因而复原数据时只需将 redis 敞开后,将备份的 rdb 文件替换以后的 rdb 文件,再启动 Redis 即可。

    留神移除 aof 文件, 否则会优先从 aof 复原.

长处

  • rdb 文件体积比拟小,适宜备份及传输
  • 性能会比 aof 好(aof 须要写入日志到文件中)
  • rdb 复原比 aof 要更快

毛病

  • 服务器故障时会失落最初一次备份之后的数据
  • Redis 保留 rdb 时,fork 子过程的这个操作期间, Redis 服务会进行响应(个别是毫秒级),但如果数据量大且 cpu 工夫缓和,则进行响应的工夫可能长达 1 秒

相干配置

################################ SNAPSHOTTING  ################################
# 快照配置
# 正文掉“save”这一行配置项就能够让保留数据库性能生效
# 设置 redis 进行数据库镜像的频率。# 900 秒(15 分钟)内至多 1 个 key 值扭转(则进行数据库保留 -- 长久化)# 300 秒(5 分钟)内至多 10 个 key 值扭转(则进行数据库保留 -- 长久化)# 60 秒(1 分钟)内至多 10000 个 key 值扭转(则进行数据库保留 -- 长久化)save 900 1
save 300 10
save 60 10000

#当 RDB 长久化呈现谬误后,是否进行,yes:进行工作,no:能够持续进行工作,能够通过 info 中的 rdb_last_bgsave_status 理解 RDB 长久化是否有谬误
stop-writes-on-bgsave-error yes

#应用压缩 rdb 文件,rdb 文件压缩应用 LZF 压缩算法,yes:压缩,然而须要一些 cpu 的耗费。no:不压缩,须要更多的磁盘空间
rdbcompression yes

#是否校验 rdb 文件。从 rdb 格局的第五个版本开始,在 rdb 文件的开端会带上 CRC64 的校验和。这跟有利于文件的容错性,然而在保留 rdb 文件的时候,会有大略 10% 的性能损耗,所以如果你谋求高性能,能够敞开该配置。rdbchecksum yes

#rdb 文件的名称
dbfilename dump.rdb

#数据目录,数据库的写入会在这个目录。rdb、aof 文件也会写在这个目录
dir /var/lib/redis

AOF

AOF 其实就是将客户端每一次操作记录追加到指定的 aof(日志)文件中,在 aof 文件体积多大时能够主动在后盾重写 aof 文件(期间不影响失常服务,中途磁盘写满或停机等导致失败也不会失落数据)

aof 长久化的 fsync 策略:

  • no : 不执行 fsync, 由操作系统保证数据同步到磁盘(linux 默认 30 秒),速度最快
  • always : 每次写入都执行 fsync, 保证数据同步到磁盘(最影响性能)
  • everysec : 每秒执行一次 fsync, 最多失落最近 1s 的数据(举荐)

fsync:同步内存中所有已批改的文件数据到贮存设施

长处:

  • 充分保证数据的长久化,正确的配置个别最多失落 1 秒的数据
  • aof 文件内容是以 Redis 协定格局保留,易读
  • 日志是追加程序写入.

毛病:

  • aof 文件比 rdb 快照大
  • 应用 aof 文件复原比 rdb 慢
  • aof 重写会造成短暂阻塞, 并耗费大量磁盘 IO

AOF 重写(bgrewriteaof)

  1. fork 子过程
  2. 子过程通过读取服务器以后的数据库状态, 并将其转化为操作命令写入 aof 临时文件

    会复制主过程的空间内存页表, 对于 10GB 的 Redis 过程,须要复制大概 20MB 的内存页表

  3. 在此期间主过程会将新的命令同时写到 AOF 缓冲区 和 AOF 重写缓冲区.
  4. 子过程写入结束后, 主过程将 AOF 重写缓冲区的内容写入 aof 临时文件, 并原子笼罩原 aof 文件.

何时会触发 AOF 重写

  • 以后没有 BGSAVE(RDB 长久化)
  • 以后没有 BGREWRITEAOF 进行
  • 用户调用 BGREWRITEAOF 手动触发
  • 依据条件主动触发

    • aof 文件大小大于 auto-aof-rewrite-min-size, 且大于增长比率 (绝对上一次重写后的 aof 文件大小) 大于 auto-aof-rewrite-percentage

相干配置参数

############################## APPEND ONLY MODE ###############################
#默认 redis 应用的是 rdb 形式长久化,这种形式在许多利用中曾经足够用了。然而 redis 如果中途宕机,会导致可能有几分钟的数据失落,依据 save 来策略进行长久化,Append Only File 是另一种长久化形式,能够提供更好的长久化个性。Redis 会把每次写入的数据在接管后都写入 appendonly.aof 文件,每次启动时 Redis 都会先把这个文件的数据读入内存里,先疏忽 RDB 文件。appendonly yes

#aof 文件名, 保留目录由 dir 参数决定
appendfilename "appendonly.aof"

#aof 长久化策略的配置
#no 示意不执行 fsync,由操作系统保证数据同步到磁盘,速度最快。#always 示意每次写入都执行 fsync,以保证数据同步到磁盘。#everysec 示意每秒执行一次 fsync,可能会导致失落这 1s 数据。appendfsync everysec

# 在 aof 重写或者写入 rdb 文件的时候,会执行大量 IO,此时对于 everysec 和 always 的 aof 模式来说,执行 fsync 会造成阻塞过长时间,no-appendfsync-on-rewrite 字段设置为默认设置为 no。如果对提早要求很高的利用,这个字段能够设置为 yes,否则还是设置为 no,这样对长久化个性来说这是更平安的抉择。设置为 yes 示意 rewrite 期间对新写操作不 fsync, 临时存在内存中, 等 rewrite 实现后再写入,默认为 no,倡议 yes。Linux 的默认 fsync 策略是 30 秒。可能失落 30 秒数据。no-appendfsync-on-rewrite no

#aof 主动重写配置。当目前 aof 文件大小超过上一次重写的 aof 文件大小的百分之多少进行重写,即当 aof 文件增长到肯定大小的时候 Redis 可能调用 bgrewriteaof 对日志文件进行重写。以后 AOF 文件大小是上次日志重写失去 AOF 文件大小的二倍(设置为 100)时,主动启动新的日志重写过程。auto-aof-rewrite-percentage 100
#设置容许重写的最小 aof 文件大小,防止了达到约定百分比但尺寸依然很小的状况还要重写
auto-aof-rewrite-min-size 64mb

#aof 文件可能在尾部是不残缺的,当 redis 启动的时候,aof 文件的数据被载入内存。重启可能产生在 redis 所在的主机操作系统宕机后,尤其在 ext4 文件系统没有加上 data=ordered 选项(redis 宕机或者异样终止不会造成尾部不残缺景象。)呈现这种景象,能够抉择让 redis 退出,或者导入尽可能多的数据。如果抉择的是 yes,当截断的 aof 文件被导入的时候,会主动公布一个 log 给客户端而后 load。如果是 no,用户必须手动 redis-check-aof 修复 AOF 文件才能够。aof-load-truncated yes

RESP 通信协定

RESP 是 redis 客户端和服务端之前应用的一种文本通信协定

RESP 的特点:实现简略、疾速解析、可读性好

距离符号: \r\n

简略字符串 Simple Strings

+ < 字符串 >\r\n

字符串不能蕴含 CR 或者 LF(不容许换行)

若要发送二进制平安的字符串, 举荐应用 Bulk Strings

eg. +OK\r\n

谬误 Errors

-< 谬误前缀 > < 错误信息 > \r\n

eg. -Error unknow command 'foobar'\r\n

错误信息不能蕴含 CR 或者 LF(不容许换行),Errors 与 Simple Strings 很类似,不同的是 Erros 会被当作异样来对待

整数型 Integer

: 数字 +r+n

eg. :1000\r\n

大字符串类型 Bulk Strings

$< 字符串的长度 >\r\n< 字符串 >\r\n

字符串不能蕴含 CR 或者 LF(不容许换行);

eg. $6\r\nfoobar\r\n, 空字符串 $0\r\n\r\n, null $-1\r\n

数组类型 Arrays

*< 数组元素个数 >\r\n< 其余所有类型 > (结尾不须要 rn)

留神:只有元素个数前面的 rn 是属于该数组的,结尾的 rn 个别是元素的

eg.

空数组
"*0\r\n"      

数组蕴含 2 个元素,别离是字符串 foo 和 bar
"*2\r\n$2\r\nfoo\r\n$3\r\nbar\r\n"      

数组蕴含 3 个整数:1、2、3
"*3\r\n:1\r\n:2\r\n:3\r\n"       

蕴含混合类型的数组
"*5\r\n:1\r\n:2\r\n:3\r\n:4\r\n$6\r\nfoobar\r\n"  

Null 数组
"*-1\r\n"         

数组嵌套,外层数组蕴含 2 个数组,"*2\r\n*3\r\n:1\r\n:2\r\n:3\r\n*2\r\n+Foo\r\n-Bar\r\n"   
整顿后如下:*2\r\n
*3\r\n:1\r\n:2\r\n:3\r\n
*2\r\n+Foo\r\n-Bar\r\n

Lua

参考链接

  • Lua: A Guide for Redis Users
  • Redis Lua 编程与调试工具应用

    Redis 自 3.2 版本开始蕴含 LDB,用于调试 Lua 脚本, LDB 反对设置断点,逐行执行等。

  • 像调试 java 一样来调试 Redis lua

    ↑ 暂未测试

执行 Lua

redis-cli --eval xxx.lua key1 key2 , argv1 argv2

留神:

  • key 和 argv 之间要用逗号分隔

示例

每分钟统计信息

-- KEYS 每分钟总负载, ZSET
-- KEYS 期待队列, LIST

-- ARGV[1] worker 序号
-- ARGV[2] 本分钟的工夫戳
-- ARGV[3] 本分钟的工夫戳对应的字符串 y-m-d H:i:s
-- ARGV[4] 本分钟内的总战斗耗时
-- ARGV[5] 本分钟内的战斗次数
-- ARGV[6] 本分钟内的战斗抛弃次数(已蕴含在下面), 指的是战斗提早过久, worker 被动摈弃
-- ARGV[7] 本分钟内的战斗出错次数(已蕴含在下面), 指的是战斗在 lua 层面上出错
-- ARGV[8] worker 过程内存占用
-- ARGV[9] worker 启动次数
-- ARGV[10] 以后工夫, 秒(携带小数局部)

local key_load_all = KEYS[1]
local key_wait_list = KEYS[2]

local worker = ARGV[1]
local cur_time = tonumber(ARGV[2])
local cur_time_str = ARGV[3]
local battle_time = tonumber(ARGV[4])
local battle_cnt = tonumber(ARGV[5])
local battle_discard_cnt = tonumber(ARGV[6])
local battle_error_cnt = tonumber(ARGV[7])
local worker_res = tonumber(ARGV[8])
local worker_start_cnt = tonumber(ARGV[9])
local time_now = ARGV[10]


local to_del

-- 每分钟的总体负载
local load_all = redis.call('ZRANGEBYSCORE', key_load_all, cur_time, cur_time);

if next(load_all) ~= nil then
    to_del = load_all[1]
    load_all = cjson.decode(load_all[1])
else
    load_all = {t = cur_time, ts = cur_time_str, battle_cost_time = 0, battle_cnt = 0, battle_error_cnt = 0, battle_discard_cnt = 0, wait_list = 0, worker_list = {}}
end
-- 总的累计, 不便查看
load_all["battle_cost_time"] = load_all["battle_cost_time"] + battle_time
load_all["battle_cnt"] = load_all["battle_cnt"] + battle_cnt
load_all["battle_error_cnt"] = load_all["battle_error_cnt"] + battle_error_cnt
load_all["battle_discard_cnt"] = load_all["battle_discard_cnt"] + battle_discard_cnt

-- 累计各个 worker
if load_all["worker_list"][worker] == nil then
    load_all["worker_list"][worker] = {battle_cost_time = 0, battle_cnt = 0, battle_error_cnt = 0, battle_discard_cnt = 0, process_res = 0, start_cnt = 0}
end
load_all["worker_list"][worker]["battle_cost_time"] = load_all["worker_list"][worker]["battle_cost_time"] + battle_time
load_all["worker_list"][worker]["battle_cnt"] = load_all["worker_list"][worker]["battle_cnt"] + battle_cnt
load_all["worker_list"][worker]["battle_error_cnt"] = load_all["worker_list"][worker]["battle_error_cnt"] + battle_error_cnt
load_all["worker_list"][worker]["battle_discard_cnt"] = load_all["worker_list"][worker]["battle_discard_cnt"] + battle_discard_cnt
-- load_all["worker_list"][worker]["process_res"] = math.max(worker_res, load_all["worker_list"][worker]["process_res"])
load_all["worker_list"][worker]["process_res"] = worker_res
load_all["worker_list"][worker]["start_cnt"] = load_all["worker_list"][worker]["start_cnt"] + worker_start_cnt

-- 工作队列长度
local wait_list = tonumber(redis.call("LLEN", key_wait_list))
load_all["wait_list"] = math.max(load_all["wait_list"], wait_list)
if wait_list > 0 then
    local wait_list_item = redis.call("LINDEX", key_wait_list, -1)
    load_all["wait_longest"] = time_now - cjson.decode(wait_list_item)["BattleStartMicoTime"]
end


redis.call("ZADD", key_load_all, cur_time, cjson.encode(load_all))
if to_del then
    redis.call("ZREM", key_load_all, to_del)
    to_del = nil
end

return 1

redis-cli 命令行客户端

# 查看以后有哪些 big key
redis-cli --bigkeys -i 0.1

big key 会导致集群中拜访 big key 时压力歪斜向对应的实例.

除了应用 redis-cli 外, 还能够应用其余工具 (rdbtools) 对 rdb 文件剖析查找 big key.

优化准则

  • hash: 对 field 取模, 进行哈希, 分成多个小的 hash
# 查看与 Redis 的提早(基于 PING 指令), 单位: 毫秒
redis-cli --latency
# 查看简略状态
redis-cli --stat
# 输入如下
# ------- data ------ --------------------- load -------------------- - child -
#keys       mem      clients blocked requests            connections
#133        3.59M    15      0       115095975 (+0)      15035835

Redis 3.* 默认配置文件中文解释

#redis.conf
# Redis configuration file example.
# ./redis-server /path/to/redis.conf

################################## INCLUDES ###################################
#这在你有标准配置模板然而每个 redis 服务器又须要共性设置的时候很有用。# include /path/to/local.conf
# include /path/to/other.conf

################################ GENERAL #####################################

#是否在后盾执行,yes:后盾运行;no:不是后盾运行(老版本默认)daemonize yes

  #3.2 里的参数,是否开启保护模式,默认开启。要是配置里没有指定 bind 和明码。开启该参数后,redis 只会本地进行拜访,回绝内部拜访。要是开启了明码   和 bind,能够开启。否   则最好敞开,设置为 no。protected-mode yes
#redis 的过程文件
pidfile /var/run/redis/redis-server.pid

#redis 监听的端口号。port 6379

#此参数确定了 TCP 连贯中已实现队列 (实现三次握手之后) 的长度,当然此值必须不大于 Linux 零碎定义的 /proc/sys/net/core/somaxconn 值,默认是 511,而 Linux 的默认参数值是 128。当零碎并发量大并且客户端速度迟缓的时候,能够将这二个参数一起参考设定。该内核参数默认值个别是 128,对于负载很大的服务程序来说大大的不够。个别会将它批改为 2048 或者更大。在 /etc/sysctl.conf 中增加:net.core.somaxconn = 2048,而后在终端中执行 sysctl -p。tcp-backlog 511

#指定 redis 只接管来自于该 IP 地址的申请,如果不进行设置,那么将解决所有申请
bind 127.0.0.1

#配置 unix socket 来让 redis 反对监听本地连接。# unixsocket /var/run/redis/redis.sock
#配置 unix socket 应用文件的权限
# unixsocketperm 700

# 此参数为设置客户端闲暇超过 timeout,服务端会断开连接,为 0 则服务端不会被动断开连接,不能小于 0。timeout 0

#tcp keepalive 参数。如果设置不为 0,就应用配置 tcp 的 SO_KEEPALIVE 值,应用 keepalive 有两个益处: 检测挂掉的对端。升高中间设备出问题而导致网络看似连贯却曾经与对端端口的问题。在 Linux 内核中,设置了 keepalive,redis 会定时给对端发送 ack。检测到对端敞开须要两倍的设置值。tcp-keepalive 0

#指定了服务端日志的级别。级别包含:debug(很多信息,不便开发、测试),verbose(许多有用的信息,然而没有 debug 级别信息多),notice(适当的日志级别,适宜生产环境),warn(只有十分重要的信息)loglevel notice

#指定了记录日志的文件。空字符串的话,日志会打印到规范输出设备。后盾运行的 redis 规范输入是 /dev/null。logfile /var/log/redis/redis-server.log

#是否关上记录 syslog 性能
# syslog-enabled no

#syslog 的标识符。# syslog-ident redis

#日志的起源、设施
# syslog-facility local0

#数据库的数量,默认应用的数据库是 DB 0。能够通过”SELECT“命令抉择一个 db
databases 16

################################ SNAPSHOTTING ################################
# 快照配置
# 正文掉“save”这一行配置项就能够让保留数据库性能生效
# 设置 sedis 进行数据库镜像的频率。# 900 秒(15 分钟)内至多 1 个 key 值扭转(则进行数据库保留 -- 长久化)# 300 秒(5 分钟)内至多 10 个 key 值扭转(则进行数据库保留 -- 长久化)# 60 秒(1 分钟)内至多 10000 个 key 值扭转(则进行数据库保留 -- 长久化)save 900 1
save 300 10
save 60 10000

#当 RDB 长久化呈现谬误后,是否仍然进行持续进行工作,yes:不能进行工作,no:能够持续进行工作,能够通过 info 中的 rdb_last_bgsave_status 理解 RDB 长久化是否有谬误
stop-writes-on-bgsave-error yes

#应用压缩 rdb 文件,rdb 文件压缩应用 LZF 压缩算法,yes:压缩,然而须要一些 cpu 的耗费。no:不压缩,须要更多的磁盘空间
rdbcompression yes

#是否校验 rdb 文件。从 rdb 格局的第五个版本开始,在 rdb 文件的开端会带上 CRC64 的校验和。这跟有利于文件的容错性,然而在保留 rdb 文件的时候,会有大略 10% 的性能损耗,所以如果你谋求高性能,能够敞开该配置。rdbchecksum yes

#rdb 文件的名称
dbfilename dump.rdb

#数据目录,数据库的写入会在这个目录。rdb、aof 文件也会写在这个目录
dir /var/lib/redis

################################# REPLICATION #################################
#复制选项,slave 复制对应的 master。# slaveof <masterip> <masterport>

#如果 master 设置了 requirepass,那么 slave 要连上 master,须要有 master 的明码才行。masterauth 就是用来配置 master 的明码,这样能够在连上 master 后进行认证。# masterauth <master-password>

#当从库同主机失去连贯或者复制正在进行,从机库有两种运行形式:1) 如果 slave-serve-stale-data 设置为 yes(默认设置),从库会持续响应客户端的申请。2) 如果 slave-serve-stale-data 设置为 no,除去 INFO 和 SLAVOF 命令之外的任何申请都会返回一个谬误”SYNC with master in progress”。slave-serve-stale-data yes

#作为从服务器,默认状况下是只读的(yes),能够批改成 NO,用于写(不倡议)。slave-read-only yes

#是否应用 socket 形式复制数据。目前 redis 复制提供两种形式,disk 和 socket。如果新的 slave 连上来或者重连的 slave 无奈局部同步,就会执行全量同步,master 会生成 rdb 文件。有 2 种形式:disk 形式是 master 创立一个新的过程把 rdb 文件保留到磁盘,再把磁盘上的 rdb 文件传递给 slave。socket 是 master 创立一个新的过程,间接把 rdb 文件以 socket 的形式发给 slave。disk 形式的时候,当一个 rdb 保留的过程中,多个 slave 都能共享这个 rdb 文件。socket 的形式就的一个个 slave 程序复制。在磁盘速度迟缓,网速快的状况下举荐用 socket 形式。repl-diskless-sync no

#diskless 复制的延迟时间,避免设置为 0。一旦复制开始,节点不会再接管新 slave 的复制申请直到下一个 rdb 传输。所以最好期待一段时间,等更多的 slave 连上来。repl-diskless-sync-delay 5

#slave 依据指定的工夫距离向服务器发送 ping 申请。工夫距离能够通过 repl_ping_slave_period 来设置,默认 10 秒。# repl-ping-slave-period 10

#复制连贯超时工夫。master 和 slave 都有超时工夫的设置。master 检测到 slave 上次发送的工夫超过 repl-timeout,即认为 slave 离线,革除该 slave 信息。slave 检测到上次和 master 交互的工夫超过 repl-timeout,则认为 master 离线。须要留神的是 repl-timeout 须要设置一个比 repl-ping-slave-period 更大的值,不然会常常检测到超时。# repl-timeout 60

#是否禁止复制 tcp 链接的 tcp nodelay 参数,可传递 yes 或者 no。默认是 no,即应用 tcp nodelay。如果 master 设置了 yes 来禁止 tcp nodelay 设置,在把数据复制给 slave 的时候,会缩小包的数量和更小的网络带宽。然而这也可能带来数据的提早。默认咱们举荐更小的提早,然而在数据量传输很大的场景下,倡议抉择 yes。repl-disable-tcp-nodelay no

#复制缓冲区大小,这是一个环形复制缓冲区,用来保留最新复制的命令。这样在 slave 离线的时候,不须要齐全复制 master 的数据,如果能够执行局部同步,只须要把缓冲区的局部数据复制给 slave,就能恢复正常复制状态。缓冲区的大小越大,slave 离线的工夫能够更长,复制缓冲区只有在有 slave 连贯的时候才分配内存。没有 slave 的一段时间,内存会被释放出来,默认 1m。# repl-backlog-size 5mb

#master 没有 slave 一段时间会开释复制缓冲区的内存,repl-backlog-ttl 用来设置该工夫长度。单位为秒。# repl-backlog-ttl 3600

#当 master 不可用,Sentinel 会依据 slave 的优先级选举一个 master。最低的优先级的 slave,入选 master。而配置成 0,永远不会被选举。slave-priority 100

#redis 提供了能够让 master 进行写入的形式,如果配置了 min-slaves-to-write,衰弱的 slave 的个数小于 N,mater 就禁止写入。master 起码得有多少个衰弱的 slave 存活能力执行写命令。这个配置尽管不能保障 N 个 slave 都肯定能接管到 master 的写操作,然而能防止没有足够衰弱的 slave 的时候,master 不能写入来防止数据失落。设置为 0 是敞开该性能。# min-slaves-to-write 0

#提早小于 min-slaves-max-lag 秒的 slave 才认为是衰弱的 slave。# min-slaves-max-lag 10

# 设置 1 或另一个设置为 0 禁用这个个性。# Setting one or the other to 0 disables the feature.
# By default min-slaves-to-write is set to 0 (feature disabled) and
# min-slaves-max-lag is set to 10.

################################## SECURITY ###################################
#requirepass 配置能够让用户应用 AUTH 命令来认证明码,能力应用其余命令。这让 redis 能够应用在不受信赖的网络中。为了放弃向后的兼容性,能够正文该命令,因为大部分用户也不须要认证。应用 requirepass 的时候须要留神,因为 redis 太快了,每秒能够认证 15w 次明码,简略的明码很容易被攻破,所以最好应用一个更简单的明码。# requirepass foobared

#把危险的命令给批改成其余名称。比方 CONFIG 命令能够重命名为一个很难被猜到的命令,这样用户不能应用,而外部工具还能接着应用。# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

#设置成一个空的值,能够禁止一个命令
# rename-command CONFIG ""
################################### LIMITS ####################################

# 设置能连上 redis 的最大客户端连贯数量。默认是 10000 个客户端连贯。因为 redis 不辨别连贯是客户端连贯还是外部关上文件或者和 slave 连贯等,所以 maxclients 最小倡议设置到 32。如果超过了 maxclients,redis 会给新的连贯发送’max number of clients reached’,并敞开连贯。# maxclients 10000

#redis 配置的最大内存容量。当内存满了,须要配合 maxmemory-policy 策略进行解决。留神 slave 的输入缓冲区是不计算在 maxmemory 内的。所以为了避免主机内存应用完,倡议设置的 maxmemory 须要更小一些。# maxmemory <bytes>

#内存容量超过 maxmemory 后的解决策略。#volatile-lru:利用 LRU 算法移除设置过过期工夫的 key。#volatile-random:随机移除设置过过期工夫的 key。#volatile-ttl:移除行将过期的 key,依据最近过期工夫来删除(辅以 TTL)#allkeys-lru:利用 LRU 算法移除任何 key。#allkeys-random:随机移除任何 key。#noeviction:不移除任何 key,只是返回一个写谬误。#下面的这些驱赶策略,如果 redis 没有适合的 key 驱赶,对于写命令,还是会返回谬误。redis 将不再接管写申请,只接管 get 申请。写命令包含:set setnx setex append incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby getset mset msetnx exec sort。# maxmemory-policy noeviction

#lru 检测的样本数。应用 lru 或者 ttl 淘汰算法,从须要淘汰的列表中随机抉择 sample 个 key,选出闲置工夫最长的 key 移除。# maxmemory-samples 5

############################## APPEND ONLY MODE ###############################
#默认 redis 应用的是 rdb 形式长久化,这种形式在许多利用中曾经足够用了。然而 redis 如果中途宕机,会导致可能有几分钟的数据失落,依据 save 来策略进行长久化,Append Only File 是另一种长久化形式,能够提供更好的长久化个性。Redis 会把每次写入的数据在接管后都写入 appendonly.aof 文件,每次启动时 Redis 都会先把这个文件的数据读入内存里,先疏忽 RDB 文件。appendonly no

#aof 文件名
appendfilename "appendonly.aof"

#aof 长久化策略的配置
#no 示意不执行 fsync,由操作系统保证数据同步到磁盘,速度最快。#always 示意每次写入都执行 fsync,以保证数据同步到磁盘。#everysec 示意每秒执行一次 fsync,可能会导致失落这 1s 数据。appendfsync everysec

# 在 aof 重写或者写入 rdb 文件的时候,会执行大量 IO,此时对于 everysec 和 always 的 aof 模式来说,执行 fsync 会造成阻塞过长时间,no-appendfsync-on-rewrite 字段设置为默认设置为 no。如果对提早要求很高的利用,这个字段能够设置为 yes,否则还是设置为 no,这样对长久化个性来说这是更平安的抉择。设置为 yes 示意 rewrite 期间对新写操作不 fsync, 临时存在内存中, 等 rewrite 实现后再写入,默认为 no,倡议 yes。Linux 的默认 fsync 策略是 30 秒。可能失落 30 秒数据。no-appendfsync-on-rewrite no

#aof 主动重写配置。当目前 aof 文件大小超过上一次重写的 aof 文件大小的百分之多少进行重写,即当 aof 文件增长到肯定大小的时候 Redis 可能调用 bgrewriteaof 对日志文件进行重写。以后 AOF 文件大小是上次日志重写失去 AOF 文件大小的二倍(设置为 100)时,主动启动新的日志重写过程。auto-aof-rewrite-percentage 100
#设置容许重写的最小 aof 文件大小,防止了达到约定百分比但尺寸依然很小的状况还要重写
auto-aof-rewrite-min-size 64mb

#aof 文件可能在尾部是不残缺的,当 redis 启动的时候,aof 文件的数据被载入内存。重启可能产生在 redis 所在的主机操作系统宕机后,尤其在 ext4 文件系统没有加上 data=ordered 选项(redis 宕机或者异样终止不会造成尾部不残缺景象。)呈现这种景象,能够抉择让 redis 退出,或者导入尽可能多的数据。如果抉择的是 yes,当截断的 aof 文件被导入的时候,会主动公布一个 log 给客户端而后 load。如果是 no,用户必须手动 redis-check-aof 修复 AOF 文件才能够。aof-load-truncated yes

################################ LUA SCRIPTING ###############################
# 如果达到最大工夫限度(毫秒),redis 会记个 log,而后返回 error。当一个脚本超过了最大时限。只有 SCRIPT KILL 和 SHUTDOWN NOSAVE 能够用。第一个能够杀没有调 write 命令的货色。要是曾经调用了 write,只能用第二个命令杀。lua-time-limit 5000

################################ REDIS CLUSTER ###############################
#集群开关,默认是不开启集群模式。# cluster-enabled yes

#集群配置文件的名称,每个节点都有一个集群相干的配置文件,长久化保留集群的信息。这个文件并不需要手动配置,这个配置文件有 Redis 生成并更新,每个 Redis 集群节点须要一个独自的配置文件,请确保与实例运行的零碎中配置文件名称不抵触
# cluster-config-file nodes-6379.conf

#节点互连超时的阀值。集群节点超时毫秒数
# cluster-node-timeout 15000

#在进行故障转移的时候,全副 slave 都会申请申请为 master,然而有些 slave 可能与 master 断开连接一段时间了,导致数据过于古老,这样的 slave 不应该被晋升为 master。该参数就是用来判断 slave 节点与 master 断线的工夫是否过长。判断办法是:#比拟 slave 断开连接的工夫和(node-timeout * slave-validity-factor) + repl-ping-slave-period
#如果节点超时工夫为三十秒, 并且 slave-validity-factor 为 10, 假如默认的 repl-ping-slave-period 是 10 秒,即如果超过 310 秒 slave 将不会尝试进行故障转移 
# cluster-slave-validity-factor 10

#master 的 slave 数量大于该值,slave 能力迁徙到其余孤立 master 上,如这个参数若被设为 2,那么只有当一个主节点领有 2 个可工作的从节点时,它的一个从节点会尝试迁徙。# cluster-migration-barrier 1

#默认状况下,集群全副的 slot 有节点负责,集群状态才为 ok,能力提供服务。设置为 no,能够在 slot 没有全副调配的时候提供服务。不倡议关上该配置,这样会造成分区的时候,小分区的 master 始终在承受写申请,而造成很长时间数据不统一。# cluster-require-full-coverage yes

################################## SLOW LOG ###################################
###slog log 是用来记录 redis 运行中执行比较慢的命令耗时。当命令的执行超过了指定工夫,就记录在 slow log 中,slog log 保留在内存中,所以没有 IO 操作。#执行工夫比 slowlog-log-slower-than 大的申请记录到 slowlog 外面,单位是微秒,所以 1000000 就是 1 秒。留神,正数工夫会禁用慢查问日志,而 0 则会强制记录所有命令。slowlog-log-slower-than 10000

#慢查问日志长度。当一个新的命令被写进日志的时候,最老的那个记录会被删掉。这个长度没有限度。只有有足够的内存就行。你能够通过 SLOWLOG RESET 来开释内存。slowlog-max-len 128

################################ LATENCY MONITOR ##############################
#提早监控性能是用来监控 redis 中执行比拟迟缓的一些操作,用 LATENCY 打印 redis 实例在跑命令时的耗时图表。只记录大于等于下边设置的值的操作。0 的话,就是敞开监督。默认提早监控性能是敞开的,如果你须要关上,也能够通过 CONFIG SET 命令动静设置。latency-monitor-threshold 0

############################# EVENT NOTIFICATION ##############################
#键空间告诉使得客户端能够通过订阅频道或模式,来接管那些以某种形式改变了 Redis 数据集的事件。因为开启键空间告诉性能须要耗费一些 CPU,所以在默认配置下,该性能处于敞开状态。#notify-keyspace-events 的参数能够是以下字符的任意组合,它指定了服务器该发送哪些类型的告诉:##K 键空间告诉,所有告诉以 __keyspace@__ 为前缀
##E 键事件告诉,所有告诉以 __keyevent@__ 为前缀
##g DEL、EXPIRE、RENAME 等类型无关的通用命令的告诉
##$ 字符串命令的告诉
##l 列表命令的告诉
##s 汇合命令的告诉
##h 哈希命令的告诉
##z 有序汇合命令的告诉
##x 过期事件:每当有过期键被删除时发送
##e 驱赶 (evict) 事件:每当有键因为 maxmemory 政策而被删除时发送
##A 参数 g$lshzxe 的别名
#输出的参数中至多要有一个 K 或者 E,否则的话,不论其余的参数是什么,都不会有任何 告诉被散发。具体应用能够参考 http://redis.io/topics/notifications

notify-keyspace-events ""

############################### ADVANCED CONFIG ###############################
#数据量小于等于 hash-max-ziplist-entries 的用 ziplist,大于 hash-max-ziplist-entries 用 hash
hash-max-ziplist-entries 512
#value 大小小于等于 hash-max-ziplist-value 的用 ziplist,大于 hash-max-ziplist-value 用 hash。hash-max-ziplist-value 64

#数据量小于等于 list-max-ziplist-entries 用 ziplist,大于 list-max-ziplist-entries 用 list。list-max-ziplist-entries 512
#value 大小小于等于 list-max-ziplist-value 的用 ziplist,大于 list-max-ziplist-value 用 list。list-max-ziplist-value 64

#数据量小于等于 set-max-intset-entries 用 iniset,大于 set-max-intset-entries 用 set。set-max-intset-entries 512

#数据量小于等于 zset-max-ziplist-entries 用 ziplist,大于 zset-max-ziplist-entries 用 zset。zset-max-ziplist-entries 128
#value 大小小于等于 zset-max-ziplist-value 用 ziplist,大于 zset-max-ziplist-value 用 zset。zset-max-ziplist-value 64

#value 大小小于等于 hll-sparse-max-bytes 应用稠密数据结构(sparse),大于 hll-sparse-max-bytes 应用浓密的数据结构(dense)。一个比 16000 大的 value 是简直没用的,倡议的 value 大略为 3000。如果对 CPU 要求不高,对空间要求较高的,倡议设置到 10000 左右。hll-sparse-max-bytes 3000

#Redis 将在每 100 毫秒时应用 1 毫秒的 CPU 工夫来对 redis 的 hash 表进行从新 hash,能够升高内存的应用。当你的应用场景中,有十分严格的实时性须要,不可能承受 Redis 时不时的对申请有 2 毫秒的提早的话,把这项配置为 no。如果没有这么严格的实时性要求,能够设置为 yes,以便可能尽可能快的开释内存。activerehashing yes

## 对客户端输入缓冲进行限度能够强制那些不从服务器读取数据的客户端断开连接,用来强制敞开传输迟缓的客户端。#对于 normal client,第一个 0 示意勾销 hard limit,第二个 0 和第三个 0 示意勾销 soft limit,normal client 默认勾销限度,因为如果没有寻问,他们是不会接收数据的。client-output-buffer-limit normal 0 0 0
#对于 slave client 和 MONITER client,如果 client-output-buffer 一旦超过 256mb,又或者超过 64mb 继续 60 秒,那么服务器就会立刻断开客户端连贯。client-output-buffer-limit slave 256mb 64mb 60
#对于 pubsub client,如果 client-output-buffer 一旦超过 32mb,又或者超过 8mb 继续 60 秒,那么服务器就会立刻断开客户端连贯。client-output-buffer-limit pubsub 32mb 8mb 60

#redis 执行工作的频率为 1s 除以 hz。hz 10

#在 aof 重写的时候,如果关上了 aof-rewrite-incremental-fsync 开关,零碎会每 32MB 执行一次 fsync。这对于把文件写入磁盘是有帮忙的,能够防止过大的提早峰值。aof-rewrite-incremental-fsync yes
退出移动版