概念 | Redis是完全开源免费的,遵守BSD协议,是-一个高性能的key-value数据库。它支持存储的value类型很多,包括string(字符串)、list(链表)、set(集合)、(Zset(有序集合),这些数据类型都支持。 push/pop、add/remove及 取交集和并集及更丰富的操作,Redis支持各种不同方式的排序)为了保证效率,数据都是缓存在内存中,它也可以周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件。 Redis字符串具有二进制安全功能,主要是指二进制文件不能执行更改文件内容的功能或者操作,把操作数据作为原始的、无任何特殊格式意义的数据流进行存储。 这就意味着字符串可以包含任意类型,比如字符串、数字、存储图片、json、或者web的css等静态文件。当然这个值也是有限制的,最大值不能超过512M。 |
特点 | Redis与其他key - value缓存产品有以下三个特点: 1. Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 2.Redis不仅仅支持简单的key-value类型的数据,同时还提供list, set , zset , hash等数据结构的存储。 3.Redis支持数据的备份,即master-slave模式的数据备份。 |
安装 | 1.下载源码包:redis-3.0.6.tar.gz 2.tar xzvf redis-3.0.6.tar.gz 3.进入redis目录cd /redis make make install prefix=指定目录 4.从源码包拷贝配置文件模板 5.启动服务 |
服 务 器 配 置修改 | 在启动服务器时,通过给定参数的方式来为配置选项设置值 | redis-server --<option1> <value1> --<option2> <value2> --<option3> <value3> ... 以下参数可以让服 务器 创建 10 个数据 库,并将服 务器的端口 设置10080: redis-server --databases10 --port 10080 |
将要修改的配置 选项以及 选项的 值记录到一个 配置文件里面,并在启 动服务器 时, 让服务 器载入该配置文件 | redis-server <path-to-config-file> 配置文件 redis.conf : databases 128 port 10086 redis-server redis.conf |
通 过使用 CONFIG 系列命令,用 户可以 在 服 务器运行 时动态修改 选项的值, 也可以通过命令获取选项当前的 值。 | CONFIG GET <option> CONFIG SET <option> <value> |
使用 CONFIG SET 需要注意的一点是, 并不是所有配置 选项都可以在服务器运行 时动态地设置的, 有一些配置选项必须在服务器启动时才能设置。CONFIG SET设置的选项值只会在服 务器运行的过程中生效,一旦服务器关机, CONFIG SET设置的选项值就会丢失。 如果服务器在启动时载入了配置文件,并且在服务器运行的过程中使用 CONFIG SET 修改了配置选项的值,那 么执行 CONFIG REWRITE 命令可以将被修改的配置选项以及它的值写入到配置文件里面 |
选项 | 作用 | 默认值 | 可在线修改? | port <num> | 服务器的监听端口号 | 6379 | 否 | timeout <seconds> | 在客 户端 处于空 闲状 态多久之后,服 务器才会自 动断开它 | 0 (不主动断开) | 是 | loglevel <level> | 服务器记录日志的级别 | notice | 是 | databases <num> | 数据库的数量 | 16 | 是 | requirepass <pswd> | 客户端连接服务器的密码 | 空密码 | 是 | maxmemory <bytes> | 可用的最大内存数量 | 不限制 | 是 | lua-time-limit <ms> | Lua 脚本正常运行的最大 时间 | 5000 | 是 | slowlog-log-slower-than | 执行 时长超过 microseconds 微秒的命令将被 记录 将这个值设置为负数表示关闭慢查询功能。 | 10000也即是1/100秒 1 秒=1百万微秒 | | slowlog-max-len | 慢查询日志的最大数量 当记录的日志超过这个数量时,新日志会覆盖旧日FIFO | 128 | | dir | 数据存放目录 | | | daemonize | 是否后台启动,默认no | | | pidfile | redis后台启动时候,会生成pid文件,指定pid路径 | | | bind | 绑定的ip地址 | | | rdbcompress | 存储到本地时是否压缩,默认为yes,redis采用lzf,当数据量较小时,考虑cpu可以关闭,数据大时考虑磁盘IO开启 | | | dbfilename | 存储的本地数据文件名称 | | | maxclient | 最大连接数默认1000 | | | vm-enable | 指定启用虚拟内存,默认no | | | vm-swap-file | 虚拟内存文件路径 | | |
|
数据结构 |
string | Redis 中最 简单的数据 结构,它既可以 储存文字(比如 "hello world"),又可以 储存数字(比如整数 10086 和浮点数 3.14), 还可以储存二进制数据(比如 10010100) |
SET | 是一个插入的操作,当我们命令执行成功之后会返回一个OK的提示。如果当前key的name存在的话,则会覆盖 还支持可 选的 NX 选项和 XX 选项: • 如果 给定了 NX 选项,那么命令 仅在 键 key 不存在 的情况下,才 进行 设置操作;如果 键 key 已 经存 在,那么 SET ... NX 命令不做 动作(不会覆盖旧 值)。 • 如果 给定了 XX 选项,那么命令 仅在 键 key 已 经存在 的情况下,才 进行设置操作;如果 键 key 不存 在,那么 SET ... XX 命令不做 动作(一定会覆盖旧 值)。 在 给定 NX 选项和 XX 选项的情况下, SET 命令在 设置成功 时返回 OK , 设置失败时返回 nil 。 SETNX key value:仅在 键 key 不存在 的情况下,将 键 key 的 值设置 为 value ,效果和 SET key value NX 一 样。 NX 的意思 为“Not eXists”(不存在)。键不存在并且 设置成功 时,命令返回 1 ;因 为键已经存在而 导致 设置失 败时,命令返回 0 。 示例: SET nx-str "this will fail" XX SET nx-str "this will success" NX SETNX new-key "i am a new key!" SETNX new-key "another new key here!"键已 经存在, 设置失 败 | get | 命令来获取值,当查询的键值为空,不存在时 ,redis返回nil一个空 | mset | 一次 为一个或多个字符串 键设置 值,效果和同 时执行多个 SET 命 令一 样。命令返回 OK 因 为 Redis 的数据 库不能出 现两个同名的 键,所以我 们通常会使用 field1::field2::field3 这样的格式 来区分同一 类型的多个字符串 键。:: 是比 较常用的分割符,你也可以 选择自己喜 欢的其他分割符来命名 键 | mget | 一次返回一个或多个字符串 键的 值,效果和同 时执行多个 GET 命 令一 样。 | GETSET key new-value | 将字符串 键的 值设置 为 new-value ,并返回字符串 键在 设置新 值之前 储存的旧 值(old value) | append | 将 值 value 推入到字符串 键 key 已 储存内容的末尾。 即使字符串 键储存的是数字 值,它也可以 执行 APPEND、 STRLEN、SETRANGE 和 GETRANGE 当用 户针对一个数字 值执行 这些命令的 时候, Redis 会先将数字 值转换为字符串,然后再 执行命令 | strlen | 返回字符串 键 key 储存的 值的 长度。 因 为 Redis 会 记录每个字符串 值的 长度,所以 获取 该值的复 杂度 为 O(1) 。 | 字符串的索引( index)以 0 为开始,从字符串的开 头向字符串的 结尾依次 递增,字符串第一个字符的索 引 为 0 ,字符串最后一个字符的索引 为 N-1 ,其中 N 为字符串的 长度。 除了(正数)索引之外,字符串 还有 负数索引: 负数索引以 -1 为开始,从字符串的 结尾向字符串的开 头 依次 递减,字符串的最后一个字符的索引 为 -N ,其中 N 为字符串的 长度。 | SETRANGE | SETRANGE key index value 从索引 index 开始,用 value 覆写( overwrite)给定 键 key 所 储存的字符串 值。 只接受正数索引。 命令返回覆写之后,字符串 值的长度。复 杂度 为 O(N), N 为 value 的长度 | GETRANGE | GETRANGE key start end 返回 键 key 储存的字符串 值中,位于 start 和 end 两个索引之 间的内容( 闭区 间, start 和 end 会被包括 在内)。和 SETRANGE 只接受正数索引不同, GETRANGE 的索引可以是正数或者 负数。 复 杂度 为 O(N) , N 为被 选中内容的 长度。 | 只要 储存在字符串 键里面的 值可以被解 释为 64 位整数,或者 IEEE-754 标准的 64 位浮点数, 那么用 户就可以对这个字符串 键执行针对数字 值的命令。 SET 、 GET 、 SETNX、 APPEND 等命令同 样可以用于 设置二 进制数据。 | INCRBY | 将 key 所 储存的 值加上增量 increment ,命 令返回操作 执行之后, 键 key 的当前 值。 如果 执行 INCRBY 或者 DECRBY 时, 键 key 不存在,那么命令会将 键 key 的 值初始化 为 0 ,然后再 执行增加或者减少操作 | decrby | 将 key 所 储存的 值减去减量 decrement ,命 令返回操作 执行之后, 键 key 的当前 值 如果 执行 INCRBY 或者 DECRBY 时, 键 key 不存在,那么命令会将 键 key 的 值初始化 为 0 ,然后再 执行增加或者减少操作 | INCR | 等同于 执行 INCRBY key 1 | decr | 等同于 执行 DECRBY key | INCRBYFLOAT | 为字符串 键 key 储存的 值加上浮点数增量 increment ,命令返回操作 执行之后, 键 key 的 值。 没有相 应的 DECRBYFLOAT ,但可以通 过给定 负值来达到 DECRBYFLOAT 的效果。 | 字符串 键在 储存二 进制位 时,索引也是从 0 开始的。但是和 储存文字时,索引 从左到右依次 递增 不同,当字符串 键储存的是二 进制位 时,二 进制位的索引会 从左到右依次 递减 | SETBIT | 将 给定索引上的二 进制位的 值设置 为 value ,命令返回被 设置的位原来 储存的旧 值。 | GETBIT | 返回 给定索引上的二 进制位的 值 | BITCOUNT | BITCOUNT key [start] [end] 计算并返回字符串 键储存的 值中,被 设置 为 1 的二 进制位的数量。 一般情况下, 给定的整个字符串 键都会 进行 计数操作,但通 过指定 额外的 start 或 end 参数,可以 让计 数只在特定索引范 围的位上 进行。 start 和 end 参数的 设置和 GETRANGE 命令 类似,都可以使用 负数 值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,以此 类推。 复 杂度 为 O(N) ,其中 N 为被 计算二 进制位的数量 | BITOP | BITOP operation destkey key [key ...] 对一个或多个保存二 进制位的字符串 键执行位元操作,并将 结果保存到 destkey 上。
BITOP AND destkey key [key ...] | 对一个或多个 key 求逻辑并,并将结果保存到 destkey 。 | BITOP OR destkey key [key ...] | 对一个或多个 key 求逻辑或,并将结果保存到 destkey 。 | BITOP XOR destkey key [key ...] | 对一个或多个 key 求逻辑异或,并将结果保存到 destkey | BITOP NOT destkey key | 对给定 key 求逻辑非,并将结果保存到 destkey | 除了 NOT 操作之外,其他操作都可以接受一个或以上数量的 key 作 为输入。 复 杂度 为 O(N) , N 为进行 计算的二 进制位数量的 总和。 命令的返回 值为计算所得结果的字 节长度,相当于 对 destkey 执行 STRLEN 。 |
|
一个英文字符只需要使用 单个字 节来 储存,而一个中文字符却需要使用多个字 节来 储存。 STRLEN、 SETRANGE 和 GETRANGE 都是 为英文 设置的,它 们只会在字符 为单个字 节的情况下正常 工作,而一旦我 们储存的是 类似中文 这样的多字节字符,那么 这三个命令就不再适用了。 redis-cli --raw# 在 redis-cli 中使用中文 时,必须打开 --raw 选项,才能正常 显示中文 SETRANGE 和 GETRANGE 的情况也是 类似的:因 为这两个命令所使用的索引是根据字 节而不是字 符来 编排的,所以 调用 SETRANGE 或者 GETRANGE 来 处理中文,得不到我 们想要的 结果。 不要使用 STRLEN、 SETRANGE 和 GETRANGE 来 处理中文。 例外情况:如果你想知道被 储存的中文包含多少个 字 节,那么可以使用 STRLEN | hash | hash是一个string类型的field和value的映射表。添加和删除操作都是O(1)(平均)的复杂度。 hash类型特别适合用于存储对象。 在field的数量在限制的范围内以及value的长度小于指定的字节数,那么此时的hash类型是用zipmap存储的,所以会比较节省内存。 可以在配置文件里面修改配置项来控制field的数量和value的字节数大小。 Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。 【注意】 hash是一个表,表里有key和对应的value。比如字典里有hash1 ,里边有{name:孤舟、age:60} 这其中name 和age 就是key 。孤舟、和60 就是value。数组的理解就是key就是数组下标、value就是数组下标对应的值 127.0.0.1:6379> hset hash1 name guzhou #创建并插入单个值
(integer) 1
127.0.0.1:6379> hset hash1 aget 30
(integer) 1
127.0.0.1:6379> hget hash1 name #获取hash表中键值为 name的 value
"guzhou"
127.0.0.1:6379> hset hash1 name guzhou1 #原来已存在,插入是则修改
(integer) 0
127.0.0.1:6379> hget hash1 name
"guzhou1"
127.0.0.1:6379> hlen hash1 #查看元素数量
(integer) 2
127.0.0.1:6379>
127.0.0.1:6379> hexists hash1 name #判断键值 name 是否存在 真 1 假 0
(integer) 1
127.0.0.1:6379> hexists hash1 sex
(integer) 0
127.0.0.1:6379> hset hash1 sex man
(integer) 1
127.0.0.1:6379> hset hash1 phone 12345678910
(integer) 1
127.0.0.1:6379> hset hash1 addr peiking
(integer) 1
127.0.0.1:6379>
127.0.0.1:6379> hget hash1 sex
"man"
127.0.0.1:6379> hget hash1 sex
"man"
127.0.0.1:6379> hdel hash1 sex name #删除1个或者多个键值
(integer) 2
127.0.0.1:6379> hget hash1 sex
(nil)
127.0.0.1:6379> hget hash1 name
(nil)
127.0.0.1:6379> hgetall hash1 #获取hash表内所有键值和数据
1) "aget"
2) "30"
3) "phone"
4) "12345678910"
5) "addr"
6) "peiking"
127.0.0.1:6379>
127.0.0.1:6379> hmset hash1 name guzhou sex man #插入多个键值和数据
OK
127.0.0.1:6379> hmget hash1 name phone #查看hash表中多个键值的value
1) "guzhou"
2) "12345678910"
127.0.0.1:6379>
127.0.0.1:6379> hkeys hash1 #查看hash表中所有的key。
1) "aget"
2) "phone"
3) "addr"
4) "name"
5) "sex"
127.0.0.1:6379> hvals hash1 #查看hash表中所有value
1) "30"
2) "12345678910"
3) "peiking"
4) "guzhou"
5) "man"
127.0.0.1:6379> | sets | Set是无序的集合。集合中的元素都是唯一的,当然是不允许出现重复数据的,主要原因在于set集合中使用hash来保持了元素的唯一性 127.0.0.1:6379> sadd set1 1 #增加1个元素
(integer) 1
127.0.0.1:6379> sadd set1 2 3 4 5 #支持增加一个或者多个元素
(integer) 4
127.0.0.1:6379>
127.0.0.1:6379> smembers set1 #查看集合中所有元素
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379> sismember set1 3 #查看值是否在集合中,在返回1
(integer) 1
127.0.0.1:6379> sismember set1 6 #查看元素是否在集合中,不存在返回0
(integer) 0
127.0.0.1:6379>
127.0.0.1:6379> sadd set1 a b c d
(integer) 4
127.0.0.1:6379> srem set1 2 #删除某个元素
(integer) 1
127.0.0.1:6379> srem set1 a
(integer) 1
127.0.0.1:6379> srem set1 b 4 #同时删除多个元素
(integer) 2
127.0.0.1:6379> smembers set1 #查看所有元素
1) "3"
2) "5"
3) "d"
4) "1"
5) "c"
127.0.0.1:6379> sadd set1 1
(integer) 0
127.0.0.1:6379> smembers set1
1) "3"
2) "5"
3) "d"
4) "1"
5) "c"
127.0.0.1:6379> sadd set1 2
(integer) 1
127.0.0.1:6379> sadd set1 1 2 3
(integer) 0
127.0.0.1:6379> smembers set1
1) "3"
2) "5"
3) "2"
4) "d"
5) "1"
6) "c"
127.0.0.1:6379> scard set1 #插损集合中有多少元素
(integer) 6
127.0.0.1:6379>
127.0.0.1:6379> scard set2
(integer) 0
127.0.0.1:6379> srandmember set1 #随机获取一个元素
"d"
127.0.0.1:6379> srandmember set1
"3"
127.0.0.1:6379> srandmember set1
"2"
127.0.0.1:6379> sadd set2 1 2 3 4 5 6
(integer) 6
127.0.0.1:6379>
127.0.0.1:6379> smove set1 set2 3 #从set1中移除,存放到set2中。本次操作由于set2中有3这个值,所以set1中移除,由于唯一性set2中,还是保持只有一个3.
(integer) 1
127.0.0.1:6379> smembers set1
1) "5"
2) "2"
3) "d"
4) "1"
5) "c"
127.0.0.1:6379> smembers set2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> smove set1 set2 d
(integer) 1
127.0.0.1:6379> smembers set1
1) "5"
2) "2"
3) "1"
4) "c"
127.0.0.1:6379> smembers set2
1) "4"
2) "3"
3) "6"
4) "5"
5) "2"
6) "1"
7) "d"
127.0.0.1:6379> sunion set1 set2 #查看两个set的合并集,唯一输出,不重复显示
1) "3"
2) "4"
3) "6"
4) "5"
5) "1"
6) "2"
7) "c"
8) "d"
127.0.0.1:6379>
127.0.0.1:6379> sinter set1 set2 #查看set1 set2的交集,共同拥有的值。
1) "5"
2) "2"
3) "1"
127.0.0.1:6379>
127.0.0.1:6379> sdiff set1 set2 #对比set1 和 set2差异(以set1为基准)
1) "c"
127.0.0.1:6379> sdiff set2 set1 #对比set2 和set1的差异(以set2为基准)
1) "4"
2) "3"
3) "d"
4) "6"
127.0.0.1:6379> | list | Redis列表是简单的字符串列表,按照插入顺序排序。 你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 LPUSH 命令插入一个新元素到列表头部,而RPUSH命令 插入一个新元素到列表的尾部。 当对一个空key执行其中某个命令时,将会创建一个新表。 类似的,如果一个操作要清空列表,那么key会从对应的key空间删除。这是个非常便利的语义, 因为如果使用一个不存在的key作为参数,所有的列表命令都会像在对一个空表操作一样。 一个列表最多可以包含232-1个元素(4294967295,每个表超过40亿个元素)。 依靠redis内存中操作数据的优势,又提供一些列实用独特的Api操控数据,用着简便,速度又快,又能实现特有的数据特征排序读写,做时间轴数据,评论列表,消息传递等等,又提供简便的分页,读写操作。优势还是蛮多的。 rpush list1 1 #rpush 在右侧插入一个值,这是第一个创建,不分左右 lrange list1 0 1 #lrange 获取list 下标 0到1,注意这里是从x到y的关系,不是x,y两个下标。 lindex list1 0 #lindex 命令 获取单个list内单个下标数据,下标从0开始,所以获取1 lrange list1 0 -1 #lrange操作,重点: -1 上边已经描述两个下标是从x到y的关系,-1 代表最后一个,所以这里会取出全部。 lpush list1 5 #lpush 命令 在list左侧,插入一个值 linsert list1 after 2 6 #linsert 命令,可以支持在某个值的前边、或者后边插入一个值,after是后边,before是前边 ,这里的 2 不是下标,是list内的值。6 则是需要插入值。 (integer) 6 lpop list1 #lpop 从左侧移除一个元素 rpop list1 #rpop 从右侧移除一个元素 ltrim list1 1 3 #ltrim 保留下标1 到 3 其余删除。 lset list1 1 hello #lset 替换下标 1 的元素 llen list1 #llen 列表长度 rpoplpush list1 list2 #rpoplpush 把list1的最后一个元素,插入到list2 的最前变。 | sorted list | Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 有序集合的成员是唯一的,但分数(score)却可以重复。 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。 【注意重点】 数据插入的时候值不可以重复,分数可以重复。大家可以理解为权重、值。两个部分组成,权重可以相同,值一定不能相同。否则插入时会覆盖 127.0.0.1:6379> zadd zset1 1 peiking #插入分支和数据。可以多个,一定要有权重
(integer) 1
127.0.0.1:6379> zadd zset1 2 shanghai
(integer) 1
127.0.0.1:6379> zadd zset1 3 guangzhou
(integer) 1
127.0.0.1:6379> zadd zset1 4 shenzhen
(integer) 1
127.0.0.1:6379> zadd zset1 5 tianjin
(integer) 1
127.0.0.1:6379> zadd zset1 6 tianjin
(integer) 0
127.0.0.1:6379> zadd zset1 7 tianjin
(integer) 0
127.0.0.1:6379> zrange zset1 0 -1 withscores #按照权重,从小到大限制, 0 -1 都是下标,代表显示全部。
1) "guzhou"
2) "1"
3) "peiking"
4) "1"
5) "guzhou2"
6) "2"
7) "shanghai"
8) "2"
9) "guangzhou"
10) "3"
11) "shenzhen"
12) "4"
13) "tianjin"
14) "7"
15) "12"
16) "100"
17) "324"
18) "2324"
127.0.0.1:6379> zrange zset1 0 1 withscores # 显示下标0 到 1 的元素
1) "guzhou"
2) "1"
3) "peiking"
4) "1"
127.0.0.1:6379> zrevrange zset1 0 -1 withscores #显示按照权重从打到小的全部显示。重点:0 -1 代表全部。
1) "324"
2) "2324"
3) "12"
4) "100"
5) "tianjin"
6) "7"
7) "shenzhen"
8) "4"
9) "guangzhou"
10) "3"
11) "shanghai"
12) "2"
13) "guzhou2"
14) "2"
15) "peiking"
16) "1"
17) "guzhou"
18) "1"
127.0.0.1:6379> zcard zset1 #统计集合中有多少元素
(integer) 9
127.0.0.1:6379> zcount zset1 1 5 #统计权重 1 到 5 中间有多少元素 。重点:权重
(integer) 6
127.0.0.1:6379> zincrby zset1 5 guangzhou #为广州这个元素增加 5 个权重。
"8"
127.0.0.1:6379> zrank zset1 guzhou #获取元素的索引、下标 从小到大排序
(integer) 0
127.0.0.1:6379> zrank zset1 shanghai
(integer) 3
127.0.0.1:6379> zscore zset1 shanghai #获取集合元素中 shanghai的权重、分值
"2"
127.0.0.1:6379>
127.0.0.1:6379> zrevrank zset1 shanghai #获取元素的索引、下标 从大到小排序
(integer) 5
127.0.0.1:6379>
127.0.0.1:6379> zrevrange zset1 0 -1 withscores
1) "324"
2) "2324"
3) "12"
4) "100"
5) "guangzhou"
6) "8"
7) "tianjin"
8) "7"
9) "shenzhen"
10) "4"
11) "shanghai"
12) "2"
13) "guzhou2"
14) "2"
15) "peiking"
16) "1"
17) "guzhou"
18) "1"
127.0.0.1:6379> zrem zset1 guzhou #删除集合中一个元素或者多个元素,空格 隔开
(integer) 1
127.0.0.1:6379> zrevrange zset1 0 -1 withscores
1) "324"
2) "2324"
3) "12"
4) "100"
5) "guangzhou"
6) "8"
7) "tianjin"
8) "7"
9) "shenzhen"
10) "4"
11) "shanghai"
12) "2"
13) "guzhou2"
14) "2"
15) "peiking"
16) "1"
127.0.0.1:6379> zrem zset1 324 12 #删除集合中一个元素或者多个元素,空格 隔开
(integer) 2
127.0.0.1:6379> zrevrange zset1 0 -1 withscores
1) "guangzhou"
2) "8"
3) "tianjin"
4) "7"
5) "shenzhen"
6) "4"
7) "shanghai"
8) "2"
9) "guzhou2"
10) "2"
11) "peiking"
12) "1"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> zremrangebyrank zset1 3 5 #按照索引删除区间(从小到大)
(integer) 3
127.0.0.1:6379> zrevrange zset1 0 -1 withscores
1) "shanghai"
2) "2"
3) "guzhou2"
4) "2"
5) "peiking"
6) "1"
127.0.0.1:6379> zremrangebyscore zset1 2 5 #按照权重范围删除元素
(integer) 2
127.0.0.1:6379> zrevrange zset1 0 -1 withscores
1) "peiking"
2) "1"
127.0.0.1:6379> | 数 据 库 |
处理数据 库中的 单个 键 | type | 返回 键 key 储存的 值的 类型。复 杂度 为 O(1) 。 | DEL | 删除 给定的任意多个 键,不存在的 键会被忽略,命 令返回被成功 删除的 键数量 | EXISTS | 检查给定的 键是否存在于数据 库,存在返回 1 ,不存在返回 0 | RENAME | 将 键的名字从 key 改 为 newkey 。 如果 newkey 已 经存在,那么覆盖 它。 键 key 不存在,或者 key 和 newkey 同名 时,返回 错误。修改成功 时返回 OK 复 杂度O(1) | RENAMENX | 如果 键 newkey 不存在,那么将 键 key 改名 为 newkey ;如果 键 newkey 已 经存在,那么不 做 动作。修改成功返回 1 ,修改失 败返回 0 复 杂度O(1) | 对键的 值进行排序 | SORT | 在 Redis 里面,只有列表和有序集合是以有序的方式来 储存 值的: • 列表按照 值被推入的顺序来 储存 值。 • 有序集合按照元素的分 值来排列元素。 通 过调用 SORT 命令,我 们也可以 对列表、集合以及有序集合 进行排序, 对于原本已 经有序的列表和 有序集合来 说,SORT 命令可以以其他方式来排列它 们的 值。 SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination] SORT 命令提供的可 选选项以及可 选参数非常多,它 们可以修改 SORT 命令在排序 时的行 为,命令的复 杂度 为 O(N+M*log(M)), N 为被排序 键包含的 值数量, M 为要返回的 值数量。 示例: SORT key将 输入 键包含的 值解释为浮点数,然后对这些浮点数 进行排序。 通 过给定 ALPHA 参数,我 们可以 让 SORT 命令基于字典序( lexicographical ordering)对文字进行排 序。 在一般情况下,有序集合里面的元素会 根据分 值来 进行排序,但是通 过执行 带有 ALPHA 参数的 SORT 命令,我 们可以 根据元素本身 来 进行排序。 在默 认情况下, SORT 命令在 进行排序的 时候,会使用 被排序 键本身包含的 值来作 为权重。但是通 过指定 BY pattern 选项,我 们可以 让 SORT 命令使用 其他键的 值来作 为权重, 对被排序键的 值 进行排序。 在默 认情况下, SORT 命令会 返回被排序 键的 值作 为返回 值,但是通 过给定 GET pattern 选项, 我 们可以 让 SORT 命令 返回其他 键的值来作 为命令的返回 值。调用一次 SORT 命令可以 给定多个 GET 选项当 给定 GET # 时,命令会返回被排序的 值本身。 SORT 命令允 许用 户通 过给定 ASC 参数或者 DESC 参数来分 别指定排序的顺序: • 给定 ASC 时,排序后的 值会以从小大到的 顺序排列(升序排列)。 • 给定 DESC 时,排序后的 值会以从大到小的 顺序排列(降序排列)。 如果不指定 顺序, SORT 默 认使用升序排列。 | 获取数据 库包含的 键 | RANDOMKEY | RANDOMKEY 从当前数据 库中随机地返回一个 键,被返回的 键不会被 删除。 如果数据 库不包含任何 键值对(为空),那么命令返回 nil 。复 杂度 为 O(1) | KEYS | KEYS pattern 返回当前数据 库中,所有匹配 给定模式 pattern 的 键 pattern 参数的 值可以是任何 glob 风格的匹配符 因 为 KEYS 命令会 一次性地遍 历整个数据 库来 获取所有与 给定模式相匹配的 键,所以随着数据 库包含 的 键值对越来越多, 这个命令的 执行㏿度也会越来越慢,而 对一个非常大的数据 库(比如包含几千万个 键值对、几 亿个 键值对)执行 KEYS 命令,将 导致服 务器被阻塞一段 时间。 为了解决 这个 问题, Redis 从 2.8.0 版本开始提供 SCAN 命令, 这个命令可以 以 渐进的方式,分多次遍 历整个数据 库,并返回匹配 给定模式的 键 | SCAN | SCAN cursor [MATCH pattern] [COUNT number] cursor 参数是遍 历时使用的游 标,在开始一次新的遍 历时,用 户需要将 cursor 设置 为 0 ,之后每次 调 用 SCAN ,命令都会返回一个新的游 标值,用 户在再次 调用 SCAN 命令 时需要 输入 这个游 标值来 继续 上次的遍 历,当命令返回的游 标为 0 时,遍 历结束。 MATCH pattern 选项用于指定要匹配的模式, 类似于 KEYS 命令的 pattern 参数。 COUNT number 选项指定 这次遍 历最多要返回多少个 键,命令 实际返回的 键数量可能比 这个 值少。有 时候,命令甚至可能会一个 键也不返回,但只要命令返回的游 标值不 为 0 ,就 说明遍 历未 结束。 number 参数的默 认值为 10 。 SCAN 命令使用的算法可以保 证,遍 历从开始到 结束期间,一直存在于数据 库里面的 键肯定会被遍 历 到,但中途被 删除或者中途添加的 键是否会被遍 历到 则是不确定的,可能会也可能不会。 另外,命令可能会返回同一个 键多次,要求无重复 结果的用 户需要自己在客 户端里面 进行 过滤。 | 对数据 库本身 进行操作 | DBSIZE | 返回数据 库目前包含的 键值对数量。复 杂度 为 O(1) 。 | SELECT | Redis 服 务器在默 认情况下会 创建 16 个数据 库,分 别为 0 号数据 库至 15 号数据 库,客户端 一般默 认使用 0 号数据 库。 每个数据 库都是独立的,一个数据 库里面的 键值 对不会 对另一个数据 库里面的 键值对有任何影 响,比如清空数据 库 X 并不会影响另一个数据 库 Y 。 另外,因 为不同数据 库提供了不同的命名空 间 (namespace),在不同数据 库里面 创建相同名字 的 键并不会㐀成 键名冲突 选择这个库之后,才可以使用我们存储的数据,进行查询,或者创建修改等等。数据库编号 ,需要使用数字表示,这个索引的起始值 0 ,select 0 的时候,就是我们默认登陆的这个库 | move | 将当前数据 库中的 键 key 移 动到目 标数据 库 target-db 里面,移 动成功返回 1 ,失 败返回 0 。 如果目 标数据库中已经有名 为 key 的 键,或者 键 key 不存在于当前数据 库,那么命令不做 动作。 复 杂度 为 O(1) 。 | FLUSHDB | 删除当前库内所有数据,慎重执行,命令不会有确认提示。执行一定成功。刚才学过select 可以创建多个库,flushdb只对当前库生效,不会删除整个实例内全部的数据。 | FLUSHALL | 删除实例中所有数据,更慎重使用,针对实例生效,执行完成之后,将全部数据被删除。 命令的复 杂度 为 O(N) , N 为所有 键值对的数 量。 命令 总返回 OK | |
|
持久化 | Redis是支持RDB和AOF两种持久化的机制,持久化的功能可以有效的避免当进程崩溃、退出时造成的数据损失。当进程退出后,我们下次启动的时候,利用之前持久化的文件马.上就可以恢复原有的数据 |
RDB | RDB持久化的方式,是在指定条件下,能对数据库进行快照存储。比如手动触发或者自动按照时间间隔。 RDB 持久化功能可以将服 务器包含的所有数据 库数据以二 进制文件的形式保存到硬 盘里面
服务器 执行客户端 发送的SAVE 命令 | 在执行 SAVE 命令的 过程中(也即是创建 RDB 文件的过程中), Redis 服务器将被阻塞,无法 处理客 户 端 发送的命令 请求,只有在 SAVE 命令 执行完 毕之后(也即是 RDB 文件 创建完 毕之后),服 务器才会 重新开始 处理客 户端 发送的命令请求。 如果 RDB 文件已 经存在,那么服 务器将自动使用新的 RDB 文件去代替旧的RDB 文件。 SAVE 命令的复 杂度 为 O(N) , N 为服务器中,所有数据库包含的键值对数量 总和 优点: 不需要创建子进程,不会消耗 额 外的内存,可以集中 资源来 创建 RDB 文件,所以 SAVE 创建 RDB 文件的㏿度会比 BGSAVE 快。 缺点: 执行期 间会阻塞服 务器。 | 服 务器执行客户端 发送的 BGSAVE 命令 | 执行 BGSAVE 命令同 样可以 创建一个新的 RDB 文件, 这个命令和 SAVE 命令的区 别在于, BGSAVE 不会㐀成 Redis 服 务器阻塞: 在 执行 BGSAVE 命令的 过程中, Redis 服 务器仍然可以正常地 处理其他 客 户端 发送的命令 请求。 BGSAVE 命令不会㐀成服 务器阻塞的原因在于: 1. 当 Redis 服 务器接收到 BGSAVE 命令的 时候,它不会自己来 创建 RDB 文件,而是通 过 fork() 来生 成一个子 进程,然后由子 进程负责创建 RDB 文件,而自己 则继续处理客 户端的命令 请求; 2. 当子 进程 创建好 RDB 文件并退出 时,它会向父 进程(也即是 负责处理命令 请求的 Redis 服 务器) 发 送一个信号,告知它 RDB 文件已 经创建完毕; 3. 最后 Redis 服 务器(父 进程)接收子 进程 创建的 RDB 文件, BGSAVE 执行完 毕。 BGSAVE 是一个异步命令, 发送命令的客 户端会立即得到回复,而 实际的操作在回复之后才开始: redis> BGSAVE BGSAVE 命令的复 杂度和 SAVE 一 样,都是 O(N) , N 为所有数据 库包含的键值对数量 总和 优点: 使得 Redis 服 务器可以在 创建 RDB 文 件的 过程中,仍然正常地 处理客 户端的 命令 请求。 缺点: 需要 创建子 进程,会耗 费额外的内存 | 使用 save配置选项设 置的自 动保存条件被 满足,服 务器自动执 行 BGSAVE 。 | 为了 让 Redis 服 务器可以自 动进行 RDB 持久化操作, Redis 提供了 save 配置 选项,通 过这个选项,用 户可以 设置任意多个保存条件,每当保存条件中的任意一个被 满足 时,服 务器就会自 动执行 BGSAVE 命令。 每次 创建 RDB 文件之后,服 务器为实现自动持久化而 设置的时间计数器和次数 计数器就会被清零, 并重新开始 计数,所以多个保存条件的效果是不会叠加的 | 这三种创建RDB文件的中,前两种情况需要用户手动行,而第三种情况则是由Redis 服务器自动执行 |
RDB 持久化有一个缺点,那就是,因 为创建 RDB 文件需要将 服 务器所有数据 库的数据 都保存起来, 这是一个非常耗 费资源和 时间的操作,所以服 务器需要隔一段 时间才 创建一个新的 RDB 文件,也即 是 说, 创建 RDB 文件的操作不能 执行得 过于 频繁,否 则就会 严重地影响服 务器的性能 |
AOF | AOF持久化是以记录命令为条件来完成的。 AOF打开的时候,对Redis的所有写操作全部按照redis的协议格式进行保存,把新的命令追加到文件末尾来完成aof文件的保存。Redis还可以同时打开RDB和AOF持久化,重启的时候优先使用AOF文件,因为AOF文件更完整. 虽然服 务器每 执行一个修改数据 库的命令,就会将被 执行的命令写入到 AOF 文件,但 这并不意味着 AOF 持久化不会 丢失任何数据
在目前常 见的操作系 统中, 执行系 统调用 write 函数,将一些内容写入到某个文件里面 时,为了提高 效率,系 统通常不会直接将内容写入到硬 盘里面,而是先将内容放入到一个内存 缓冲区( buffer)里面, 等到 缓冲区被填 满,或者用 户执行 fsync 调用和 fdatasync 调用 时,才将 储存在 缓冲区里面的内容真 正地写入到硬 盘里面. 为了控制 Redis 服 务器在遇到意外停机 时丢失的数据量, Redis 为 AOF 持久化提供了 appendfsync 选项 | always | 服 务器每写入一个命令,就 调用一次 fdatasync ,将 缓冲区里面的命令写入到硬 盘里面。在 这种模式下,服 务器即使遭遇意外停机,也不会 丢失任何已 经成功 执行的命令数据。 | everysec | 服 务器每秒钟调用一次 fdatasync ,将 缓冲区里面的命令写入到硬 盘里面。在这种模式下, 服 务器遭遇意外停机 时,最多只 丢失一秒钟内 执行的命令数据 | no | 服 务器不主动调用 fdatasync ,由操作系 统决定何 时将 缓冲区里面的命令写入到硬 盘里面。在 这种 模式下,服 务器遭遇意外停机 时, 丢失命令的数量是不确定的 | | 运行速度: always 的速度慢, everysec 和 no 都很快。 默 认值: everysec | 随着服 务器的不断运行, 为了 记录数据 库发生的 变化,服 务器会将越来越多的命令写入到 AOF 文件 里面,使得 AOF 文件的体 积不断地增大。 为了 让 AOF 文件的大小控制在合理的范 围,避免它胡乱地增 长, Redis 提供了 AOF 重写功能,通 过 这个功能,服 务器可以 产生一个新的 AOF 文件: • 新 AOF 文件 记录的数据 库数据和原有 AOF 文件 记录的数据 库数据完全一 样; • 新的 AOF 文件会使用尽可能少的命令来 记录数据 库数据,因此新 AOF 文件的体 积通常会比原 有 AOF 文件的体 积要小得多。•AOF 重写期 间,服 务器不会被阻塞,可以正常 处理客 户端 发送的命令 请求
触 发 A O F 重写 | 客 户端向服 务器发送 BGREWRITEAOF 命令 | 通 过设置配置 选项来让服 务器自 动执行 BGREWRITEAOF 命令,它 们分 别是: • auto-aof-rewrite-min-size <size> ,触 发 AOF 重写所需的最小体 积:只有在 AOF 文件的体 积 大于等于 size 时,服 务器才会考 虑是否需要 进行 AOF 重写。 这个 选项用于避免 对体 积过小的 AOF 文件 进行重写。 • auto-aof-rewrite-percentage <percent> ,指定触 发重写所需的 AOF 文件体 积百分比:当 AOF 文件的体 积大于 auto-aof-rewrite-min-size 指定的体 积,并且超过上一次重写之后的 AOF 文件 体 积的 percent% 时,就会触 发 AOF 重写。(如果服 务器 刚刚启 动不久, 还没有 进行 过 AOF 重 写,那么使用服 务器启动时载入的 AOF 文件的体 积来作为基准值。)将 这个值设置为 0 表示关 闭自 动 AOF 重写 |
![](https://i-blog.csdnimg.cn/blog_migrate/568a3ff6ede1d114e28b8c5b905bf241.png) ![](https://i-blog.csdnimg.cn/blog_migrate/64f0476fd7861e184bdce472fb72b646.png) | |
rdb与aof比较 |
RDB 持久化 | AOF 持久化 | 全量 备份,一次保存整个数据 库。 | 增量 备份,一次保存一个修改数据 库的命令。 | 保存的 间隔较长。 | 保存的 间隔默认为一秒 钟 | 数据 还原速度快。 | 数据 还原速度一般。冗余命令越多, 还原速度越慢。 | 执行 SAVE 命令 时会阻塞服 务器,但手 动或者 自 动触 发的 BGSAVE 都不会阻塞服 务器。 | 无 论是平 时还是 进行 AOF 重写 时,都不会阻塞服 务 器。 | 更适合数据 备份。 | 更适合用来保存数据,通常意 义上的数据持久化。 在 appendfsync always 模式下运行 时,Redis 的持久 化方式和一般的 SQL 数据 库的持久化方式是一 样 的。 |
|
命令 |
auth | 解锁 | 解锁redis密码,比如我们通过配置文件中 requirepass 这个值设置了密码,我们在使用redis时,需要通过auth这个命令来解锁。否则提示未认证 ((error) NOAUTH Authentication required.) 也可以登录时,使用 -a 参数,指定密码 比如 ./bin/redis-cli -h 127.0.0.1 -p 6379 -a 123456 密码为123456 | PING | 检查网络连接以及服务器是否正常运作 | 使用客 户端向 Redis 服 务器 发送一个 PING ,如果客 户端与服 务器之 间的 连接正常,并且服 务器的运 作也正常的 话,那么命令将返回一个 PONG | INFO | 查看服 务器 当前的状态 信息和统计 信息。 | INFO [section] 查看 Redis 服 务器的各种信息和 统计数 值。 通过给定可选的 section 参数,可以指定命令要返回的信息内容
all | 所有服务器信息 | default默认值 | 默认被选中的,最常见也最重要的一些服务器信息。 | server | 服 务器本身的信息,比如版本号、 监听端口号、服 务器ID 等等。 | clients | 已连接客户端的信息,比如已连接客户端的数量、正在被阻塞的客户端数量等 等 | memoery | 内存信息,比如内存占用数量、使用的内存分配器等等。 | persistence | 和 RDB 持久化以及 AOF 持久化有关的信息,比如 RDB 持久化是否正在 进行、 AOF 文件重写是否正在 进行等等。 | stats | 服 务器的 统计信息,比如已 处理的命令 请求数量、每秒 钟处理的命令 请求数量等等。 | replication | | cpu | 和主从复制有关的信息,比如服 务器的角色、主从服 务器的 连接状 态是否正常等等。 服 务器的系 统 CPU 占用量和用 户 CPU 占用量。 | commandstats | 命令 执行的 统计信息,比如命令 执行的次数、命令耗 费的 CPU 时间、 执行每个命令 耗 费的平均 CPU 时间等等。 | cluster | 集群功能的相关信息。 | keyspace | 和数据 库键空 间有关的信息,比如数据 库的 键数量、数据 库已 经被 删除的 过期键数量等等。 | | MONITOR | 查看服务器正在执行的命令。 | 实时地打印出 Redis 服 务器接收到的命令,格式 为“时间戳 [数据 库号 码 IP地址和端口号 ] 被 执行的命 令 ”。 | SLOWLOG | 记录并查看执行时间超过指定时长的命令。 | SLOWLOG GET [number] 如果 给定可 选的 number 参数,那么只返回最多 number 条日志;否 则的 话,返回所有慢 查询日志。 SLOWLOG LEN 查看目前已有的慢 查询日志数量 SLOWLOG RESE 删除所有慢 查询日志 | requirepass | 加锁服务器使用 AUTH 命令解锁 | redis-server --requirepass helloworld 当客 户端 连接一个 带密 码的服 务器 时,它必 须执行 AUTH <password> 命令来 进行解锁,否则这个客 户端就不能 执行除 AUTH 以外的其他命令 | SHUTDOWN | 关闭服务器 | SHUTDOWN [option] 在不 给定 option 参数的情况下,服 务器会先 执行持久化操作: • 如果打开了 AOF 持久化,那么 调用 fdatasync ,确保之前 执行的命令能 够被写入到硬 盘。 • 如果打开了 RDB 持久化并且数据 库已 经发生了 变化,那么 执行 SAVE 命令。 在以上操作都完成之后,服 务器关闭。 在打开了持久化功能的情况下,使用 SHUTDOWN 命令关 闭服务器不会 丢失任何数据。 option 选项的 值可以是 save 或者 nosave : • SHUTDOWN save 在关 闭之前 总是 执行 SAVE 命令,用于在没有开启 RDB 持久化的情况 下, 创建一个 RDB 文件来保存数据; • SHUTDOWN nosave 在关 闭之前不 执行 SAVE 命令,用于在数据 库可能已 经出 错的情况下,避 免将 错误的数据保存到 RDB 文件里面。 | LASTSAVE | | 这个命令查看上次执行的bgsave命令完成时间。返回的为Unix 的时间戳 | client | | kill:ip:port 可以杀掉某个连接,需要输入ip和端口 list:查看当前连接的客户端。 |
|
S e n t i n e l | 主从复制原理 | 主从数据同步是基于妙级的同步。在主从复制过程中,主从都不会被阻塞。 在从库配置完成启动之后,不管是第一次同步还是重新同步,slave都会发送一-个sync的命令给master。master接受到请求之后执行bgsave的操作,保存一个rdb文件。在保存期间,所有的数据修改操作, master都会保存在一个缓冲区内。首先不论一个或者多个slave来请求, master都可以使用这个rdb文件发送给slave , slave接收到rdb文件之后,将文件内的数据加载到内存中。完成之后,master会把缓冲区的写入操作通过redis命令协议的方式,全部发送个slave。这样的话, slave就可以拥有一份和master一样的数据。 |
创建从服务器 | 1. 使用 SLAVEOF <master-ip> <master-port> 命令,比如向一个服 务器 发送SLAVEOF 127.0.0.1 6379 ,可以让接收到该命令的服务器变为 127.0.0.1:6379 的从服 务器。 在将一个服 务器 设置成从服 务器之后,可以通 过向它 发送 SLAVEOF no one 来 让它 变回一个主 服 务器(数据 库已有的数据会被保留)。 2. 在启 动服 务器 时,通 过设置 slaveof <master-ip> <master-port> 配置 选项来 让服 务器成 为指定 服 务器的从服 务器。 |
Sentinel是一个分布式的服务,独立于redis运行。可以监控主从服务器状态,判断节点状态,并且通过投票方式,实现故障转移。 把其中的slave升级为master,并且通知应用新的master |
启动Sentinel | 1.通过执行 Redis 安装文件 夹中的 redis-sentinel 程序,可以启 动一个 Sentinel 实例 redis-sentinel sentinel.conf 2.因 为Redis的 Sentinel 实际上就是一个运行在Sentienl 模式下的Redis服务器,所以我 们同样可以使用以下命令来启 动一个 Sentinel 实例:redis-server sentinel.conf --sentinel |
原理 | 每个 Sentinel 实例可以监视任意多个主服 务器,以及被监视的主服 务器属下的所有从服务器 多个 Sentinel 实例可以监视同一个主服 务器, 监视 相同主服 务器的 这些 Sentinel 们会自动地互相 连 接, 组成一个分布式的 Sentinel 网 络,互相通信并交 换彼此关于被 监视服务器的信息。 当一个 Sentinel 认为被 监视的服 务器已 经下 线 时,它会向网 络中的其他 Sentinel 进行确 认,判断 该服 务器是否真的已 经下 线。 如果下线的服务器为主服 务器,那么 Sentinel 网 络将 对下 线主服 务器 进行自 动故障 转移:通 过将下 线主服 务器的某个从服 务器提升 为新的服务器,并 让其他从服 务器转为复制新的主服 务器,以此来 让 系 统重新回到上 线状 态 |
定时任务 | 1 )一般每个Sentinel服务器需要每间隔10s一次的频率向它所监控master和slaves发送INFO命令。通过这个任务可以发现Slaves节点是否有增加或者删除。当一 个Master被标记为下线时,会修改为每秒发送一次命令。如果info返回拓扑结构发现slave出现增加或删除,则会实时更新sentinel监控列表。 |
2 )每个Sentinel以每秒钟一次的频率向已知的master、slaves 以及其他的Sentinel实例发送一个ping命令。如果ping命令无法得到一个有效的回复,并且距离上次响应时间超过down-afer-milliseconds选项设定的值,则会被标记为主观下线 |
3 )每个Sentinel会以每2秒-次的频率,通过发布订阅的功能,向其他监视的主服务器和从服务器的所有sentinel:hello频道发送一条信息, 信息中包含了Sentinel 的IP地址、端口号和运行ID ( runid )。 通过此任务,可以查找之前未出现过的sentinel ( looking for unknown sentinels)。当Sentinel发现一个新的Sentinel时,它会将新的Sentinel添加到列表中,并与该节点创建连接,这个列表保存了Sentinel 已知的监视同一个主服务器的所有其他Sentinel。 Sentine|发送的信息还包括完整的主服务器的当前配置。如果一个Sentinel 包涵的主服务器的配置比Sentinel发送的配置要旧,那么这个Sentinel会立即更新配置。 Sentinel节点之间的交换主节点状态信息,会作为后边客观下线以及领导者选举的依据 |
故障转移 | 在执行故障转移的时候,首先是要从redis的slave中找到一个节点来作为新的Master,新的Master需要通过以下三个方面考虑: 过滤、主观下线、断线、5秒内没回复过Sentinel节点ping相应的,也过滤与主节点超过 down-afer-milliseconds 10秒的节点。 筛选之后优先选择复制偏移量最大的(也是复制最完整的)作为新的master。 如果复制偏移量不可用,或者偏移量大家都相同的时候,那么选择运行ID最小的Slave作为新的Master。 |
配置 | 一个 Sentinel 配置文件至少要包含一个 监视配置 选项,用于指定被 监视主服 务器的相关信息: sentinel monitor <name> <ip> <port> <quorum> 其中 name 是用 户为被 监视主服 务器 设置的名字,而 ip 和 port 则是被 监视主服 务器的 IP 地址和 端口号, quorum 为确 认这个主服 务器已下 线所需要的最少 Sentinel 数量。 Sentinel 可以自 动发现并监视主服务器属下的所有从服 务器,所以用 户只需要 给出主服 务器的地址和 端口号就可以了 port 26379 #port
daemonize yes #后台启动
dir /usr/local/redis/data #工作目录
logfile "/usrloca/redislog/sentinellog" #日志目录
sentinel monitor mymaster 192 168.188.1916379 2 #监控master,当判定失败时,至少需要两个
#sentinel判定失败才可以,mymaster为别名
sentinel down-after-milliseconds mymaster 10000 # sentinel判定失败的时间,单位为毫秒
mastersentinel parallel-syncs mymaster 1 #故障转移后每次有多少slave向master发起复制请求sentinel failover-timeout mymaster 60000 #1、同1个Sentinel对同1个master的两次failover的间隔
#时间从其中一个slave开始同步master出错开始计算,直
#到master被纠正。
#1111111111111111我w1..分割红1111111111111111.#以下配置是当所有Sentine!节点启动之后,自动写入的配置
//自动发现的两个slave节点
sentinel known-slave mymaster 192 168.188.1906379sentinel known-slave mymaster 192 168.188.1896379//自动发现的两个Sentinel节点
sentinel known-sentinel mymaster 192. 168.188.18926379 814149a8600fec
sentinel known-sentinel mymaster 192. 168.188.19126379 9ec521108aacc
sentinel current -epoch 0 # 当前配置信息版本,
#sentinel monitor mymaster 192.168. 188.191 6379 2这个配置项,我们需要注意的是,最后投票数是根#据我们实际的sentinel的数量来决定的,一般这个数值是 (sentinel集群數量/2+1)也就是我们通常说的一半#以上。
# sentine! down-fter-milliseconds mymaster 10000这个配置项的单位前边也讲过是毫秒。实际#
#上我们设置的10秒来判定。这个数值需要注意的就是,如果太大出现问题时需要等待判定的时间越长,损失就#
#越大。但是如果数值设置太小,一些网络波动,实际上master没有问题的情况下,又有可能出现过于敏感。在
#网络波动的情况下出现主从切换 |
t w e m p r o x y | twemproxy 是 twitter 开 发的一个代理服 务器,它兼容 Redis 和 Memcached ,允 许用 户将多个 Redis 服 务器 添加到一个服 务器池( pool)里面,并通 过用 户选择的散 列函数和分布函数,将来自客 户端的命令 请求分 发给 服 务器池中的各个服 务器。 通过使用 twemproxy ,我 们可以将数据 库分片到多台 Redis 服 务器上面,并使用 这些服 务器来分担系 统负责 以及数据 库容量:在服 务器硬件条件相同的情况下, 对 于一个包含 N 台 Redis 服 务器的池来 说,池中每台服 务器平均包含整个数据 库数据的 1/N ,并 处理平均 1/N 的客 户端命令 请求。 向池里面添加更多服 务器可以 线性地 扩展系 统处理命 令 请求的能力,以及系 统能 够保存的数据量 |
安装 | 下 载并解 压压缩包: http://code.google.com/p/twemproxy/downloads/list #在1台机器上安装wemproxy
tar xf autoconf-2.69.tar.gz
cd autoconf-2.69
#如果不配就放到了/usr/local下面了,放/usr这里就自动放在/usr/bin下面的了
./ configure --prefix=/usr
make
make install
autoconf -V
tar xf automake-1. 15. tar.gz
./configure --prefix=/usr
make
make install
tar xf libtool-2. 4.5.tar.gz
. /configure - prefix=/usr
make
make install
tar xf twemproxy-0. 4.1. tar.gz
cd twemproxy-0.4.1
aclocal --> aclocal .m4
autoconf
mkdir config
autoheader
libtoolize
automake -a
#此时里面才有configure
./ configuremake
make install
#启动需要/usr/1ocal/sbin/nutcracker |
配置 | #nutcracker -c nutcracker.yml 使用 yml 格式 编写配置文件:
my_redis_server_group: # 服 务器池的名字,支持 创建多个服 务器池
listen: 127.0.0.1:22121 # 这个服 务器池的 监听地址和端口号
hash: fnv1a_64# 键散列算法,用于将 键映射 为一个散列 值
distribution: ketama # 键分布算法,决定 键被分布到哪个服 务器
redis: true
servers:
- 127.0.0.1:6379:1
- 127.0.0.1:6380:1
- 127.0.0.1:6381:1
|
特点 | ■前端使用 Twemproxy做代理,后端的Redis数据能基本上根据key来进行比较均衡的分布 ■后端一台Redis挂掉后, Twemproxy能够自动摘除。恢复后, Twemproxy能够自动识别、恢复并重新加入到Redis组中重新使用 ■Redis 挂掉后,后端数据是否丢失依据Redis本身的持久化策略配置,与 Twemproxy基本无关 ■如果要新增加一台Redis , Twemproxy需要重启才能生效;并且数据不会自动重新Reblance ,需要人工单独写脚本来实现 如原来已经有2个节点Redis ,后续有增加2个Redis ,则数据分布计算与原来的Redis分布无关,现有数据如果需要分布均匀的话,需要人工单独处理 ■如果Twemproxy的后端节点数量发生变化, Twemproxy相同算法的前提下,原来的数据必须重新处理分布,否则会存在找不到key值的情况 ■不管 Twemproxy后端有几台Redis ,前端的单个Twemproxy的性能最大也只能和单台Redis性能差不多 ■如同时部署多台Twemproxy配置-样,客户端分别连接多台Twemproxy可以在定条件下提高性能 |
使用 | 用 户可以使用 Redis 客 户端 连接上 twemproxy ,并向 twemproxy 发送命令 请求,接收到命令 请求的 twemproxy 会根据用 户指定的散列函数和分布函数来决定将命令交 给哪个服 务器来 处理。 当 twemproxy 获取到命令 请求的回复 时,就会将命令回复返回 给发送命令 请求的客 户端,整个代理 过程 对于客 户端来 说是完全透明的。 |
键值分布 | 通 过散列函数和分布函数来将数据 库的 键放置到不同的服 务器里面。 当客 户端向 twemproxy 发送一个 针对键 key 的命令 请求 时, twemproxy 会根据以下公式 计算出 应该由 服 务器池中的哪个服 务器来 处理这个命令 请求。 # 计算 键 key 的散列 值 hash_value = hash_function(key) # 根据 键 key 的散列 值, 计算出 键 key 应该被分布到哪个服 务器里面 # 其中 all_servers_in_pool 是一个列表,它包含了池中的所有服 务器的 IP 地址和端口号 # 比如 [‘127.0.0.1:6379’, ‘127.0.0.1:6380’. ‘127.0.0.1:6381’] server = distribution_funtion(hash_value, all_servers_in_pool) # 将 请求 发送 给服 务器 forward_request(server, request) |
散列函数 | twemproxy 提供了多种散列函数供用 户选择,用 户可以通 过修改配置文件中 hash 选项的 值来指定自 己想要使用的散列函数 包括 one at a time 算法 在内的 Jenkins 散列函数 包括 crc16 、 crc32 和 crc32a 在内的 循环冗余校 验和函数 md5 散列算法 包括 fnv1_64 、 fnv1a_64 、 fnv1_32 和 fnv1a_32 在内的 Fowler Noll Vo 散列函数 由 Paul Hsieh 发明的 hsieh 散列算法 murmur 散列算法每个散列函数适用的数据 类型、它 们的分布率以及 计算㏿度等情况都不尽相同,用 户可以先了解一下 这些函数,然后再根据自己的情况来 选择合适的散列函数 |
分布函数 | 用 户可以通 过修改 distribution 选项的 值来改 变 twemproxy 分布 键的方式, 选项的 值可以是: ketama:一致性 hash ,主要用于在 实现缓存服务时,防止某个服 务器下线而成 缓存大量失效 http://www.audioscrobbler.net/development/ketama/ modula:取模运算,相当于依靠散列函数本身来分布各个 键。random :不考 虑散列 值,直接随机地将 键分布到池中的某个服 务器,在 访问键时,也随机 选择一个 服 务器来 进行 访问。 |
散列标签 | 在默 认情况下, twemproxy 会根据 键的整个 键名来计算键的散列 值,但如果用户通 过 hash_tag 选项 指定了散列 标签(hash tag),那么 twemproxy 只会根据 键名中被散列 标签包 围的部分来 计算键的散列 值。 举个例子,假 设用 户设置了配置 hash_tag: "{}" ,那么以下两个 键将 计算出相同的散列 值,因 为它 们散 列 标签中包含的内容相同 —— 都是 user : bbs::{user}::123456 bbs::{user}::255255 而 键 bbs::{topic}::98765 则可能会 计算出与以上两个 键不同的散列 值,因 为这个键在散列 标签中包含 的内容并不相同。 散列 标签可以自由 设置,比如 对于 键 bbs::$user$::123456 就可以使用 “$$” 作 为标签、键 bbs::(user):: 123456 就可以使用 “()” 作 为标签、而 键 bbs::*user*::123456 就可以使用 “**” 作 为标签, 诸如此 类。 |
服务器下线管理 | 自 动移除下 线服务器和自 动添加重新上 线的服 务器 为了解决服 务器下线的 问题, twemproxy 提供了 auto_eject_hosts <bool> 和 server_failure_limit <N> 这两个配置 选项: 当 auto_eject_hosts 选项的值为 true ,并且 twemproxy 在 连续 N 次向同一个服 务器 发送命令 请求但都遇到 错误时, twemproxy 就会将 该服 务器 标记为下 线,并 将原本由 这个服 务器 负责处理的键交 给池中的其他在 线的服 务器来 处理。 当 twemproxy 连续 N 次向同一个服 务器 发送命令 请求都遇到错误时, twemproxy 就会将该服 务器 标记 为下 线,并将原本由 这个服务器 负责处理的 键交 给池中的其他在 线的服 务器来 处理 |
| 服务器上线管理 | twemproxy 提供了 server_retry_timeout <time> 选项, time 参数的格式 为毫秒。 当一个服 务器被 twemproxy 判断 为下 线之后,在 time 毫秒之内, twemproxy 不会再 尝试向下 线的服 务 器 发送命令 请求,但是在 time 毫秒之后,服 务器会 尝试重新向下 线的服务器发送命令 请求:如果命令 请求能 够正常 执行,那么 twemproxy 就会撤 销对该服 务器的下 线判断,并再次将 键交 给 那个服 务器来处理。但如果服 务器 还是不能正常 处理命令 请求,那么 twemproxy 就会 继续将原本 应该交 给下 线服 务器 的 键转交 给其他服 务器来 处理,并等待下一次重 试的来 临。 |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
安全 | 危险命令禁用 配置文件安全模块中进行配置 | rename-command KEYS "" rename-command KEYS "abc" rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command CONFIG "" |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |