非关系型数据库redis

关系型数据库:
特点:
速度慢,数据是存储在硬盘上。
扩展性差,复杂

非关系型数据库又称NoSQL,not only SQL是对关系型数据库的一种补充。redis就是非关系数据库中的一种。

非关系型数据库redis:
特点:
速度快,数据是存储在内存上的(解决速度慢的问题)
原理:当存储数据的时候会把数据存储到MySQL中去,然后MySQL中会存储一份数据,当查询数据时,会去redis中查询若没有查询到去MySQL中查,如果在MySQL中查询到数据,会把查询到的数据插入到redis中去,下次再去查时,可以从redis中直接获取这份数据。
非关系型数据库是以键值对的方式存储数据,所以扩展性比较好。
故redis常用做缓存,也可以叫做缓存数据库。

数据读操作流程:
在这里插入图片描述
数据更新操作流程:
在这里插入图片描述

Redis 安装及连接

查看yum仓库redis版本

[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum info redis

yum安装redis

[root@localhost ~]# yum -y install redis
[root@localhost ~]# systemctl enable --now redis
[root@localhost ~]# pstree -p |grep redis
[root@localhost ~]# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info

前台启动redis
redis-server 是redis 服务器程序

[root@localhost src]# redis-server --help
Usage: ./redis-server [/path/to/redis.conf] [options]
./redis-server - (read config from stdin)
./redis-server -v or --version
./redis-server -h or --help
./redis-server --test-memory <megabytes>
Examples:
./redis-server (run the server with default conf)
./redis-server /etc/redis/6379.conf
./redis-server --port 7777
./redis-server --port 7777 --replicaof 127.0.0.1 8888
./redis-server /etc/myredis.conf --loglevel verbose
Sentinel mode:
./redis-server /etc/sentinel.conf --sentinel

前台启动redis

[root@localhost src]# redis-server /apps/redis/etc/redis.conf
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 11791
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

[root@localhost ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port
Peer Address:Port
LISTEN 0 128 127.0.0.1:6379
*:*

Redis 常用命令

INFO

显示当前节点redis运行状态信息

127.0.0.1:6379> info

SELECT

切换数据库,相当于在MySQL的 USE DBNAME 指令

127.0.0.1:6379> select 0
OK
127.0.0.1:6379> select 15
OK
127.0.0.1:6379[15]> select 16
(error) ERR DB index is out of range

注意: 在 redis cluster 模式下不支持多个数据库,会出现下面错误

127.0.0.1:6379> info cluster
# Cluster
cluster_enabled:1
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> select 1
(error) ERR SELECT is not allowed in cluster mode

KEYS

查看当前库下的所有key,此命令慎用!
在这里插入图片描述

127.0.0.1:6379[1]> SELECT 0
OK
127.0.0.1:6379> KEYS * #匹配数据库内所有key
1) "port1"
2) "name"
3) "port2"
4) "port"
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> KEYS *
(empty list or set)
127.0.0.1:6379[1]>
127.0.0.1:6379> SELECT 1
OK
#一次设置4个key
127.0.0.1:6379[1]> MSET one 1 two 2 three 3 four 4
OK
127.0.0.1:6379[1]> KEYS *o*
1) "two"
2) "one"
3) "four"

BGSAVE

手动在后台执行RDB持久化操作

#交互式执行
127.0.0.1:6379[1]> BGSAVE
Background saving started
[root@centos8 ~]# ll /apps/redis/data/
total 664
-rw-r--r-- 1 redis redis 204 Oct 22 21:30 dump_6379.rdb
#非交互式执行
[root@centos8 ~]# redis-cli -a centos --no-auth-warning bgsave
Background saving started
[root@centos8 ~]# ll /apps/redis/data/
total 664
-rw-r--r-- 1 redis redis 204 Oct 22 21:32 dump_6379.rdb

DBSIZE

返回当前库下的所有key 数量

127.0.0.1:6379> DBSIZE
(integer) 8
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> DBSIZE
(integer) 4
127.0.0.1:6379[1]> SELECT 2
OK
127.0.0.1:6379[2]> DBSIZE
(integer) 0

FLUSHDB

强制清空当前库中的所有key,此命令慎用!

127.0.0.1:6379[2]> SELECT 1
OK
127.0.0.1:6379[1]> DBSIZE
(integer) 4
127.0.0.1:6379[1]> FLUSHDB
OK
127.0.0.1:6379[1]> DBSIZE
(integer) 0

FLUSHALL

强制清空当前redis服务器所有数据库中的所有key,即删除所有数据,此命令慎用!

127.0.0.1:6379> FLUSHALL
OK
#生产建议修改配置 /etc/redis.conf,禁用或改为别名
rename-command FLUSHALL ""

SHUTDOWN

  • SHUTDOWN 命令执行以下操作:
    • 停止所有客户端
    • 如果有至少一个保存点在等待,执行 SAVE 命令
    • 如果 AOF 选项被打开,更新 AOF 文件
    • 关闭 redis 服务器(server)
  • 如果持久化被打开的话, SHUTDOWN 命令会保证服务器正常关闭而不丢失任何数据。
  • 另一方面,假如只是单纯地执行 SAVE 命令,然后再执行 QUIT 命令,则没有这一保证因为在执行SAVE 之后、执行 QUIT 之前的这段时间中间,其他客户端可能正在和服务器进行通讯,这时如果执行QUIT 就会造成数据丢失。

redis 数据类型

在这里插入图片描述字符串 string

  • 添加一个key
    • set 指令可以创建一个key并赋值,使用格式
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> set title ceo ex 5 #设置自动过期时间为5秒
OK
127.0.0.1:6379> get title
"ceo"
127.0.0.1:6379> get title
(nil)
127.0.0.1:6379> set NAME eagle #大小写敏感
OK
127.0.0.1:6379> get name
(nil)
#key不存在才设置,相当于add
127.0.0.1:6379> set name eagle
OK
127.0.0.1:6379> get name
"eagle"
127.0.0.1:6379> set name sls nx #不存在才设置
(nil)
127.0.0.1:6379> get name
"eagle"
#key存在才设置,相当于update
127.0.0.1:6379> get name
"eagle"
127.0.0.1:6379> set name sls xx #存在才设置进行覆盖
OK
127.0.0.1:6379> get name
"sls"
127.0.0.1:6379> get age
(nil)
#key不存在不设置,存在才覆盖
127.0.0.1:6379> set age 18 xx
(nil)
127.0.0.1:6379> get age
(nil)
  • 获取一个key的内容
127.0.0.1:6379> get name
"sls"
127.0.0.1:6379> get name age
(error) ERR wrong number of arguments for 'get' command
127.0.0.1:6379> mget name age
  • 删除一个和多个key
127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> del age NAME
(integer) 2
  • 批量设置多个key
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
  • 批量获取多个key
127.0.0.1:6379> mget k1 k2
1) "v1"
2) "v2"
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"
127.0.0.1:6379> keys k*
1) "k2"
2) "k3"
3) "k1"
  • 追加数据
127.0.0.1:6379> append k2 " append new value"
(integer) 19
127.0.0.1:6379> get k2
"v2 append new value"
  • 设置新值并返回旧值
127.0.0.1:6379> set name eagle
OK
127.0.0.1:6379> getset name sls
"eagle"
127.0.0.1:6379> get name
"sls"
  • 返回字符串key对应值的字节数
127.0.0.1:6379> set name eagle
OK
127.0.0.1:6379> strlen name #返回字节数
(integer) 5
127.0.0.1:6379> append name " sls"
(integer) 9
127.0.0.1:6379> get name
"eagle sls"
127.0.0.1:6379> strlen name
(integer) 9
127.0.0.1:6379> set name '好好学习'
OK
127.0.0.1:6379> strlen name
(integer) 12
  • 判断key是否存在
127.0.0.1:6379> set name eagle ex 5
OK
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists name
(integer) 0
  • 查看key的过期时间
    • ttl key #查看key的剩余生存时间,如果key过期后,会自动删除
      • -1 #返回值表示永不过期,默认创建的key是永不过期,重新对key赋值,也会从有剩余生命周期变成永不过期
      • -2 #返回值表示没有此key
      • num #key的剩余有效期
127.0.0.1:6379> ttl age
(integer) -2
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> set name eagle ex 20
OK
127.0.0.1:6379> ttl name
(integer) 18
127.0.0.1:6379> ttl k1
(integer) -1
  • 重新设置key的过期时间
127.0.0.1:6379> set name eagle ex 20
OK
127.0.0.1:6379> expire name 30
(integer) 1
127.0.0.1:6379> ttl name
(integer) 29
  • 取消key的过期时间
127.0.0.1:6379> ttl name
(integer) 5
127.0.0.1:6379> persist name #使键永久存在
(integer) 1
127.0.0.1:6379> ttl name
(integer) -1
  • 数值递增
    • 利用INCR命令簇(INCR, DECR,[INCRBY],DECRBY)来把字符串当作原子计数器使用
127.0.0.1:6379> set num 21
OK
127.0.0.1:6379> incr num
(integer) 22
127.0.0.1:6379> get num
"22"
  • 数值递减
127.0.0.1:6379> set num 21
OK
127.0.0.1:6379> decr num
(integer) 20
127.0.0.1:6379> get num
"20"
  • 数值增加
    将key对应的数字加decrement(可以是负数)。如果key不存在,操作之前,key就会被置为0。如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。这个操作最多支持64位有符号的正型数字。
127.0.0.1:6379> set num 30
OK
127.0.0.1:6379> incrby num 20
(integer) 50
127.0.0.1:6379> get num
"50"
127.0.0.1:6379> incrby num -20
(integer) 30
127.0.0.1:6379> get num
"30"
127.0.0.1:6379> get num1
(nil)
127.0.0.1:6379> incrby num1 5
(integer) 5
127.0.0.1:6379> get num1
"5"

列表 list


列表是一个双向可读写的管道,其头部是左侧,尾部是右侧,一个列表最多可以包含2^32-1(4294967295)个元素,下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,元素值可以重
复,常用于存入日志等场景,此数据类型比较常用

  • 列表特点
    • 有序
    • 可重复
    • 左右都可以操作
  • 生成列表并插入数据

在这里插入图片描述

  • LPUSH和RPUSH都可以插入列表
127.0.0.1:6379> lpush name eagle cs xwz tj
(integer) 4
127.0.0.1:6379> type name
list
127.0.0.1:6379> rpush course linux python go
(integer) 3
127.0.0.1:6379> type course
list
  • 向列表追加数据
127.0.0.1:6379> lpush name abc
(integer) 5
127.0.0.1:6379> rpush name tom
(integer) 6
  • 获取列表长度(元素个数)
127.0.0.1:6379> llen name
(integer) 6
  • 获取列表指定位置数据
    在这里插入图片描述
127.0.0.1:6379> lpush list1 a b c d
(integer) 4
127.0.0.1:6379> lindex list1 0 #获取0编号的元素
"d"
127.0.0.1:6379> lindex list1 3 #获取3编号的元素
"a"
127.0.0.1:6379> lindex list1 -1 #获取最后一个的元素
"a"
127.0.0.1:6379> lrange list1 1 2
1) "c"
2) "b"
127.0.0.1:6379> lrange list1 0 3 #所有元素
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> lrange list1 0 -1 #所有元素
1) "d"
2) "c"
3) "b"
4) "a"
  • 修改列表指定索引值
127.0.0.1:6379> lrange list1 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> rpush listkey a b c d e f
(integer) 6
127.0.0.1:6379> lrange listkey 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
127.0.0.1:6379> lset listkey 2 redis
OK
127.0.0.1:6379> lrange listkey 0 -1
1) "a"
2) "b"
3) "redis"
4) "d"
5) "e"
6) "f
  • 移除列表数据
127.0.0.1:6379> lpush list1 a b c d
(integer) 4
127.0.0.1:6379> lrange list1 0 3
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> lpop list1 #弹出左边第一个元素,即删除第一个
"d"
127.0.0.1:6379> rpop list1 #弹出右边第一个元素,即删除最后一个
"a"
127.0.0.1:6379> llen list1
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "c"
2) "b"
* LTRIM 对一个列表进行修剪(trim),让列表只保留指定区间内的元素,不在指定区间之内的元素都
将被删除
127.0.0.1:6379> lrange list1 0 3
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> ltrim list1 1 2
OK
127.0.0.1:6379> lrange list1 0 -1
1) "c"
2) "b"
  • 删除list
127.0.0.1:6379> del list1
(integer) 1
127.0.0.1:6379> exists list1
(integer) 0

集合set

Set 是 String 类型的无序集合,集合中的成员是唯一的,这就意味着集合中不能出现重复的数据,可以在两个不同的集合中对数据进行对比并取值,常用于取值判断,统计,交集等场景

  • 集合特点
    • 无序
    • 无重复
    • 集合间操作
  • 生成集合key
127.0.0.1:6379> sadd set1 v1
(integer) 1
127.0.0.1:6379> sadd set2 v2 v3
(integer) 2
127.0.0.1:6379> type set1
set
127.0.0.1:6379> type set2
set
  • 追加数值
    • 追加时,只能追加不存在的数据,不能追加以及存在的数据
127.0.0.1:6379> sadd set1 v1 #已存在的值,无法再次添加
(integer) 0
127.0.0.1:6379> sadd set1 v3 v4 v5
(integer) 3
  • 查看集合的所有数据
127.0.0.1:6379> smembers set1
1) "v3"
2) "v5"
3) "v4"
4) "v1"
127.0.0.1:6379> smembers set2
1) "v3"
2) "v2"
  • 删除集合中的元素
127.0.0.1:6379> sadd goods mobile car laptop
(integer) 3
127.0.0.1:6379> srem goods car
(integer) 1
127.0.0.1:6379> smembers goods
1) "mobile"
2) "laptop"
  • 获取集合的交集
127.0.0.1:6379> smembers set1
1) "v3"
2) "v5"
3) "v4"
4) "v1"
127.0.0.1:6379> smembers set2
1) "v3"
2) "v2"
127.0.0.1:6379> sinter set1 set2
1) "v3"
  • 获取集合的并集
127.0.0.1:6379> sunion set1 set2
1) "v1"
2) "v4"
3) "v5"
4) "v3"
5) "v2"
  • 获取集合的差集
127.0.0.1:6379> sdiff set1 set2
1) "v1"
2) "v4"
3) "v5"

有序集合sorted set

Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个double(双精度浮点型)类型的分数,redis正是通过该分数来为集合中的成员进行从小到大的排序,有序集合的成员是唯一的,但分数(score)却可以重复,集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1), 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员),经常用于排行榜的场景

  • 有序集合特点
    • 有序
    • 无重复元素
    • 每个元素都是由score和value组成
    • score可以重复
    • value不可以重复
  • 生成有序集合
127.0.0.1:6379> zadd zset1 1 v1 #分数为1
(integer) 1
127.0.0.1:6379> zadd zset1 2 v2
(integer) 1
127.0.0.1:6379> zadd zset1 2 v3 #分数可重复,元素值不可以重复
(integer) 1
127.0.0.1:6379> zadd zset1 3 v4
(integer) 1
127.0.0.1:6379> type zset1
zset
127.0.0.1:6379> zadd zset2 1 v1 2 v2 3 v3 4 v4 5 v5 #一次生成多个数据
(integer) 5
  • 有序集合实现排行榜
127.0.0.1:6379> zadd phb 90 xwz 95 tj 30 sg
(integer) 3
127.0.0.1:6379> zrange phb 0 -1
#正序排序后显示集合内所有的key,score从小到大显示
1) "sg"
2) "xwz"
3) "tj"
127.0.0.1:6379> zrevrange phb 0 -1
#倒叙排序后显示集合内所有的key,score从大到小显示
1) "tj"
2) "xwz"
3) "sg"
127.0.0.1:6379> zrevrange phb 0 -1 withscores
#正序显示指定集合内所有key和得分情况
1) "tj"
2) "95"
3) "xwz"
4) "90"
5) "sg"
6) "30"
  • 获取集合的个数
127.0.0.1:6379> zcard phb
(integer) 3
  • 基于索引返回数值
127.0.0.1:6379> zrange phb 0 2
1) "sg"
2) "xwz"
3) "tj"
127.0.0.1:6379> zrange phb 0 -1
1) "sg"
2) "xwz"
3) "tj"
  • 返回某个数值的索引
127.0.0.1:6379> zadd phb 90 sls 95 tj 30 sg
(integer) 3
127.0.0.1:6379> zrange phb 0 -1
1) "sg"
2) "xwz"
3) "tj"
127.0.0.1:6379> zrank phb sg
(integer) 0
127.0.0.1:6379> zrank phb tj
(integer) 2
  • 获取分数
127.0.0.1:6379> zscore phb tj
"95"
127.0.0.1:6379> zscore phb sg
"30"
  • 删除元素
127.0.0.1:6379> zrem phb sg tj
(integer) 2
127.0.0.1:6379> zrange phb 0 -1
1) "xwz"

哈希hash

hash 是一个string类型的字段(field)和值(value)的映射表,Redis 中每个 hash 可以存储 2^32 -1 键值对,类似于字典,存放了多个k/v 对,hash特别适合用于存储对象场景

  • 生成hash key
127.0.0.1:6379> hset 9527 name sg age 30
(integer) 2
127.0.0.1:6379> type 9527
hash
127.0.0.1:6379> hgetall 9527
1) "name"
2) "sg"
3) "age"
4) "30"
#增加字段
127.0.0.1:6379> hset 9527 gender man
(integer) 1
127.0.0.1:6379> hgetall 9527
1) "name"
2) "sg"
3) "age"
4) "30"
5) "gender"
6) "man"
  • 获取hash key的对应字段的值
127.0.0.1:6379> hget 9527 name
"sg"
127.0.0.1:6379> hget 9527 gender
"man"
127.0.0.1:6379> hmget 9527 age gender #获取多个值
1) "30"
2) "man"
  • 删除一个hash key的对应字段
127.0.0.1:6379> hdel 9527 age
(integer) 1
127.0.0.1:6379> hget 9527 age
(nil)
  • 批量设置hash key的多个field和value
127.0.0.1:6379> hmset 1024 name xls age 28 city changzhou
OK
127.0.0.1:6379> hgetall 1024
1) "name"
2) "xls"
3) "age"
4) "28"
5) "city"
6) "changzhou"
  • 获取hash中指定字段的值
127.0.0.1:6379> hmget 1024 name city
1) "xls"
2) "changzhou"
  • 获取hash中的所有字段名field
127.0.0.1:6379> hkeys 1024
1) "name"
2) "age"
3) "city"
  • 获取hash key对应所有field的value
127.0.0.1:6379> hvals 1024
1) "xls"
2) "28"
3) "changzhou"
  • 获取指定hash key的所有field及value
127.0.0.1:6379> hgetall 1024
1) "name"
2) "xls"
3) "age"
4) "28"
5) "city"
6) "changzhou"
  • 删除hash
127.0.0.1:6379> del 1024
(integer) 1
127.0.0.1:6379> hmget 1024 name age
1) (nil)
2) (nil)
127.0.0.1:6379> exists 1024
(integer) 0

redis的其他特性

慢查询
在这里插入图片描述- 可以通过config set命令动态修改参数,并使配置持久化到配置文件中

config set slowlog-log-slower-than 20000
config set slowlog-max-len 1000
config rewrite
  • 获取慢查询日志,将慢查询的时间改为1微秒
127.0.0.1:6379> config set slowlog-log-slower-than 1
OK
127.0.0.1:6379> config set slowlog-max-len 1000
OK
127.0.0.1:6379> SLOWLOG len
# 获取慢查询日志列表当前的长度
(integer) 2
127.0.0.1:6379> SLOWLOG get
1) 1) (integer) 2
2) (integer) 1625544379
3) (integer) 1
4) 1) "SLOWLOG"
2) "len"
5) "127.0.0.1:40294"
6) ""
2) 1) (integer) 1
2) (integer) 1625544372
3) (integer) 4
4) 1) "config"
2) "set"
3) "slowlog-max-len"
4) "1000"
5) "127.0.0.1:40294"
6) ""
3) 1) (integer) 0
2) (integer) 1625544363
3) (integer) 3
4) 1) "config"
2) "set"
3) "slowlog-log-slower-than"
4) "1"
5) "127.0.0.1:40294"
6) ""
  • 可以看到每个慢查询日志有4个属性组成,分别是慢查询日志的标识id、发生时间戳、命令耗时、执行命令和参数
  • 慢查询日志重置
127.0.0.1:6379> slowlog reset
OK
127.0.0.1:6379> slowlog len
(integer) 0

Redis shell

  • -r(repeat)选项代表将命令执行多次,例如下面操作将会执行三次ping 命令
redis-cli -r 3 ping
PONG
PONG
PONG
  • -i(interval)选项代表每隔几秒执行一次命令,但是-i选项必须和-r选 项一起使用,下面的操作会每隔1秒执行一次ping命令,一共执行5次
$ redis-cli -r 5 -i 1 ping
PONG
PONG
PONG
PONG
PONG
  • -x选项代表从标准输入(stdin)读取数据作为redis-cli的最后一个参 数,例如下面的操作会将字符串world作为set hello的值:
$ echo "world" | redis-cli -x set hello
OK
  • -c(cluster)选项是连接Redis Cluster节点时需要使用的,-c选项可以防 止moved和ask异常
  • 如果Redis配置了密码,可以用-a(auth)选项,有了这个选项就不需要 手动输入auth命令

redis-server 详解

  • redis-server- -test-memory可以用来检测当前操作系统能否稳定地分配指定容量的内存给 Redis,通过这种检测可以有效避免因为内存问题造成Redis崩溃,例如下面 操作检测当前操作系统能否提供1G的内存给Redis
redis-server --test-memory 1024
  • 整个内存检测的时间比较长。当输出passed this test时说明内存检测完毕

redis-benchmark详解

  • redis-benchmark可以为Redis做基准性能测试,它提供了很多选项帮助开发和运维人员测试Redis的相关性能
  • -c(clients)选项代表客户端的并发数量(默认是50)。
  • -n(num)选项代表客户端请求总量(默认是100000)。
  • -q选项仅仅显示redis-benchmark的requests per second信息。
  • 在一个空的Redis上执行了redis-benchmark会发现只有3个键, 如果想向Redis插入更多的键,可以执行使用-r(random)选项,可以向 Redis插入更多随机的键。

Pipeline

  • Redis提供了批量操作命令(例如mget、mset等),有效地节约RTT。但 大部分命令是不支持批量操作的,例如要执行n次hgetall命令,并没有 mhgetall命令存在,需要消耗n次RTT。
  • Pipeline(流水线)机制能改善上面这类问题,它能将一组Redis命令进 行组装,通过一次RTT传输给Redis,再将这组Redis命令的执行结果按顺序返回给客户端
    在这里插入图片描述
echo -en
'*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n*2\r\n$4\r\nincr\r\
n$7\r\ncounter\r\n' | redis-cli --pipe

Bitmaps

位图

  • 设置值
setbit key offset value
127.0.0.1:6379> setbit unique:users:2016-04-05 0 1
(integer) 0
127.0.0.1:6379> setbit unique:users:2016-04-05 5 1
(integer) 0
127.0.0.1:6379> setbit unique:users:2016-04-05 11 1
(integer) 0
127.0.0.1:6379> setbit unique:users:2016-04-05 15 1
(integer) 0
127.0.0.1:6379> setbit unique:users:2016-04-05 19 1
(integer) 0

在这里插入图片描述

  • 获取值
getbit key offset
127.0.0.1:6379> getbit unique:users:2016-04-05 8
(integer) 0
  • 获取Bitmaps指定范围值为1的个数
bitcount [start][end]
下面操作计算2016-04-05这天的独立访问用户数量:
127.0.0.1:6379> bitcount unique:users:2016-04-05
(integer) 5
[start][end]代表起始和结束字节数,下面操作计算用户id在第1个字节
到第3个字节之间的独立访问用户数,对应的用户id是111519127.0.0.1:6379> bitcount unique:users:2016-04-05 1 3
(integer) 3
  • Bitmaps间的运算
bitop是一个复合操作,它可以做多个Bitmaps的and(交集)、or(并
集)、not(非)、xor(异或)操作并将结果保存在destkey中。
bitop op destkey key[key....]
计算出2016-04-042016-04-03两天都访问过网站的用户数
127.0.0.1:6379> bitop and unique:users:and:2016-04-04_03 unique: users:2016-
04-03
unique:users:2016-04-03
(integer) 2
127.0.0.1:6379> bitcount unique:users:and:2016-04-04_03
(integer) 2

消息队列

  • 消息队列: 把要传输的数据放在队列中
  • 功能: 可以实现多个系统之间的解耦,异步,削峰/限流等
  • 常用的消息队列应用: kafka,rabbitMQ,redis
    在这里插入图片描述消息队列主要分为两种,这两种模式Redis都支持
  • 生产者/消费者模式
  • 发布者/订阅者模式

生产者消费者模式
在生产者/消费者(Producer/Consumer)模式下,上层应用接收到的外部请求后开始处理其当前步骤的操作,在执行完成后将已经完成的操作发送至指定的频道(channel,逻辑队列)当中,并由其下层的应用监听
该频道并继续下一步的操作,如果其处理完成后没有下一步的操作就直接返回数据给外部请求,如果还有下一步的操作就再将任务发布到另外一个频道,由另外一个消费者继续监听和处理。
模式介绍

  • 生产者发布消息
[root@localhost ~]# redis-cli
127.0.0.1:6379> lpush channel1 msg1
(integer) 1
127.0.0.1:6379> lpush channel1 msg2
(integer) 2
127.0.0.1:6379> lpush channel1 msg3
(integer) 3
127.0.0.1:6379> lpush channel1 msg4
(integer) 4
127.0.0.1:6379> lpush channel1 msg5
(integer) 5
  • 消费者消费消息
127.0.0.1:6379> rpop channel1
"msg1"
127.0.0.1:6379> rpop channel1
"msg2"
127.0.0.1:6379> rpop channel1
"msg3"
127.0.0.1:6379> rpop channel1
"msg4"
127.0.0.1:6379> rpop channel1
"msg5"
127.0.0.1:6379> rpop channel1
(nil)

发布订阅
Redis提供了基于“发布/订阅”模式的消息机制,此种模式下,消息发布 者和订阅者不进行直接通信,发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息

  • 发布消息
publish channel message
下面操作会向channel:sports频道发布一条消息“Tim won the
championship”,返回结果为订阅者个数,因为此时没有订阅,所以返回结果
为0127.0.0.1:6379> publish channel:sports "Tim won the championship"
(integer) 0
  • 订阅消息
subscribe channel [channel ...]
订阅者可以订阅一个或多个频道,下面操作为当前客户端订阅了
channel:sports频道:
127.0.0.1:6379> subscribe channel:sports
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel:sports"
3) (integer) 1
  • 取消订阅
unsubscribe [channel [channel ...]]
客户端可以通过unsubscribe命令取消对指定频道的订阅,取消成功后,
不会再收到该频道的发布消息:
127.0.0.1:6379> unsubscribe channel:sports
1) "unsubscribe"
2) "channel:sports"
3) (integer) 0
  • 按照模式订阅和取消订阅
psubscribe pattern [pattern...]
punsubscribe [pattern [pattern ...]]
除了subcribe和unsubscribe命令,Redis命令还支持glob风格的订阅命令
psubscribe和取消订阅命令punsubscribe,例如下面操作订阅以it开头的所有
频道:
127.0.0.1:6379> psubscribe it*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "it*"
  • 查询订阅
1)查看活跃的频道
pubsub channels [pattern]
所谓活跃的频道是指当前频道至少有一个订阅者,其中[pattern]是可以
指定具体的模式:
127.0.0.1:6379> pubsub channels
1) "channel:sports"
2) "channel:it"
3) "channel:travel"
127.0.0.1:6379> pubsub channels channel:*r*
1) "channel:sports"
2) "channel:travel"2)查看频道订阅数
pubsub numsub [channel ...]
当前channel:sports频道的订阅数为2127.0.0.1:6379> pubsub numsub channel:sports
1) "channel:sports"
2) (integer) 23)查看模式订阅数
pubsub numpat
当前只有一个客户端通过模式来订阅:
127.0.0.1:6379> pubsub numpat
(integer) 1

GEO

Redis3.2版本提供了GEO(地理信息定位)功能,支持存储地理位置信 息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能,对于需要实现这些功能的开发者来说是一大福音。

  • 增加地理位置信息
geoadd key longitude latitude member [longitude latitude member ...]
127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing
(integer) 1
127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing
(integer) 0
27.0.0.1:6379> geoadd cities:locations 117.12 39.08 tianjin 114.29 38.02
shijiazhuang 118.01 39.38 tangshan 115.29 38.51 baoding
(integer) 4
  • 获取地理位置信息
geopos key member [member ...]
下面操作会获取天津的经维度:
127.0.0.1:6379> geopos cities:locations tianjin
1) 1) "117.12000042200088501"
2) "39.0800000535766543"
  • 获取两个地理位置的距离
geodist key member1 member2 [unit]
其中unit代表返回结果的单位,包含以下四种:
m(meters)代表米。
km(kilometers)代表公里。
mi(miles)代表英里。
ft(feet)代表尺。
127.0.0.1:6379> geodist cities:locations tianjin beijing km
"89.2061"
  • 获取指定位置范围内的地理信息位置集合
georadius key longitude latitude radiusm|km|ft|mi [withcoord] [withdist]
[withhash] [COUNT count] [asc|desc] [store key] [storedist key]
georadiusbymember key member radiusm|km|ft|mi [withcoord] [withdist]
[withhash] [COUNT count] [asc|desc] [store key] [storedist key]
withcoord:返回结果中包含经纬度。
withdist:返回结果中包含离中心节点位置的距离。
withhash:返回结果中包含geohash,有关geohash后面介绍。
COUNT count:指定返回结果的数量。
asc|desc:返回结果按照离中心节点的距离做升序或者降序。
store key:将返回结果的地理位置信息保存到指定键。
storedist key:将返回结果离中心节点的距离保存到指定键
127.0.0.1:6379> georadiusbymember cities:locations beijing 150 km
1) "beijing"
2) "tianjin"
3) "tangshan"
4) "baoding"
  • 删除地理位置信息
GEO没有提供删除成员的命令,但是因为GEO的底层实现是zset,所以
可以借用zrem命令实现对地理位置信息的删除
zrem key member

数据持久化

Redis支持RDB和AOF两种持久化机制,持久化功能能有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前之间持久化的文件即可实现数据恢复。简单点说,redis是将数据运行在内存中的,如果出现服务挂掉或者服务器宕机都可以导致数据全部丢失,为了解决这个问题redis提供了两种解决方案,分别是rdb、aof

RDB持久化

  • RDB持久是把当前数据生成快照保存到硬盘的过程
  • 触发RDB持久化过程为手动触发和自动触发
  • 优点
    • RDB是一个非常紧凑(compact)的文件,它保存了redis 在某个时间点上的数据集。这种文件非常适合用于进 行备份和灾难恢复。
    • RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
  • 缺点
    • RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于 重量级操作(内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑),频繁执行成本过高(影响性能)
    • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无 法兼容新版RDB格式的问题(版本不兼容)
    • 在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失)

触发方式

  • 自动触发:主配置文件中的save字段
  • 手动触发
    • save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。
    • bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。
    • 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则 自动执行bgsave。

BGSAVE流程说明

在这里插入图片描述1. 执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进 程,如RDB/AOF子进程,如果
存在bgsave命令直接返回。
2. 父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通 过info stats命令查看
latest_fork_usec选项,可以获取最近一个fork操作的耗 时,单位为微秒。
3. 父进程fork完成后,bgsave命令返回“Background saving started”信息 并不再阻塞父进程,可以
继续响应其他命令。
4. 子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后 对原有文件进行原子替换。执行
lastsave命令可以获取最后一次生成RDB的 时间,对应info统计的rdb_last_save_time选项。
5. 进程发送信号给父进程表示完成,父进程更新统计信息,
简单来说,父进程fork出来子进程,子进程去生成一个RDB文件(dump.rdb)
运维提示

  • 当遇到坏盘或磁盘写满等情况时,可以通过config set dir{newDir}在线 修改文件路径到可用的磁盘路径,之后执行bgsave进行磁盘切换,同样适用 于AOF持久化文件。
  • Redis默认采用LZF算法对生成的RDB文件做压缩处理,压缩后的 文件远远小于内存大小,默认开启,可以通过参数config set rdbcompression{yes|no}动态修改。
  • 如果想要恢复相关数据,只需要将相关的RDB文件拷贝到相关的目录下面即可,redis启动时会自动将rdb文件里的内容加载到内存中。

AOF持久化

  • AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。
  • AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。
  • 优点
    • AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就丢失 1 秒的数据而已。
    • AOF 文件使用 Redis 命令追加的形式来构造,因此,即使 Redis 只能向 AOF 文件写入命令的片断,使用 redis-check-aof 工具也很容易修正 AOF 文件。
    • AOF 文件的格式可读性较强,这也为使用者提供了更灵活的处理方式。例如,如果我们不小心错用了 FLUSHALL 命令,在重写还没进行时,我们可以手工将最后的 FLUSHALL 命令去掉,然后再使用 AOF 来恢 复数据。
  • 缺点
    • 对于具有相同数据的的 Redis,AOF 文件通常会比 RDB 文件体积更大。
    • 虽然 AOF 提供了多种同步的频率,默认情况下,每秒同步一次的频率也具有较高的性能。但在 Redis 的负载 较高时,RDB 比 AOF 具好更好的性能保证。
    • RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF文件中,因此从理论上说,RDB 比 AOF 方式更健壮。官方文档也指出,AOF 的确也存在一些 BUG,这些 BUG 在 RDB 没有 存在。
      使用AOF
  • 开启AOF功能需要设置配置:appendonly yes,默认不开启。AOF文件名 通过appendfilename配置设置,默认文件名是appendonly.aof。保存路径同 RDB持久化方式一致,通过dir配置指定。
appendonly yes # 将配置文件中appendonly字段设置为yes即可 1

工作流程

在这里插入图片描述1. 所有的写入命令会追加到aof_buf(缓冲区)中。
2. AOF缓冲区根据对应的策略向硬盘做同步操作。
3. 随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩 的目的。
4. 当Redis服务器重启时,可以加载AOF文件进行数据恢复。

重写机制:
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis 引入AOF重写机制压缩文件体积。

  • 重写后的AOF文件会变小,原因如下
    • 进程内已经超时的数据不再写入文件。
    • 旧的AOF文件含有无效命令,如del key1、hdel key2、srem keys、set a111、set a222等。重写使用进程内数据直接生成,这样新的AOF文件只保 留最终数据的写入命令。
    • 多条写命令可以合并为一个,如:lpush list a、lpush list b、lpush list c可以转化为:lpush list a b c。为了防止单条命令过大造成客户端缓冲区溢 出,对于list、set、hash、zset等类型操作,以64个元素为界拆分为多条。
  • 手动触发:直接调用bgrewriteaof命令
  • 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参 数确定自动触发时机。
    在这里插入图片描述1. 执行AOF重写请求。
  1. 父进程执行fork创建子进程,开销等同于bgsave过程。
    3.1 主进程fork操作完成后,继续响应其他命令。所有修改命令依然写 入AOF缓冲区并根据appendfsync策略同步到硬盘,保证原有AOF机制正确性。
    3.2 由于fork操作运用写时复制技术,子进程只能共享fork操作时的内 存数据。由于父进程依然响
    应命令,Redis使用“AOF重写缓冲区”保存这部 分新数据,防止新AOF文件生成期间丢失这部分数
    据。
  2. 子进程根据内存快照,按照命令合并规则写入到新的AOF文件。每 次批量写入硬盘数据量由配置
    aof-rewrite-incremental-fsync控制,默认为 32MB,防止单次刷盘数据过多造成硬盘阻塞。
    4.子进程重写AOF文件,并将重写的文件aof_rewrite_buf追加到新重写的文件中。
    5.1 新AOF文件写入完成后,子进程发送信号给父进程,父进程更新 统计信息,具体见info persistence
    下的aof_*相关统计。
    5.2 父进程把AOF重写缓冲区的数据写入到新的AOF文件。
    5.3 使用新AOF文件替换老文件,完成AOF重写。

aof_buf代表相应其他请求。

重启加载持久化文件

在这里插入图片描述1. AOF持久化开启且存在AOF文件时,优先加载AOF文件
2. AOF关闭或者AOF文件不存在时,加载RDB文件
3. 加载AOF/RDB文件成功后,Redis启动成功。
4. AOF/RDB文件存在错误时,Redis启动失败并打印错误信息。

架构–主从复制

  • 在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到 其他机器,满足故障恢复和
    负载均衡等需求。Redis也是如此。
  • 优点
    • 满足故障和负载均衡等要求
  • 缺点
    • 若主节点出现问题,则不能提供服务,需要人工修改配置将从变主,无法实现高可用。
    • 主从复制主节点的写能力有限
    • 单机节点的存储能力有限

数据同步方式

全量同步

  • Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。步骤如下:
    • 从服务器连接主服务器,发送SYNC命令;
    • 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
    • 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
    • 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
    • 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
    • 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

增量同步

  • Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
  • 增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
    同步策略
  • 主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave在任何时候都可 以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

部署主从复制

  • 一台主服务器的配置文件
#/bin/bash
mkdir /usr/local/redis/{data,conf,log} -pv
cat << EOF > /usr/local/redis/conf/redis6380.conf
bind 127.0.0.1
port 6380
daemonize yes
pidfile /usr/local/redis/redis_6380.pid
loglevel notice
logfile /usr/local/redis/log/redis_6380.log
dir /usr/local/redis/data/
EOF
  • 两台从服务器的配置文件
cat << EOF > /usr/local/redis/conf/redis6381.conf
bind 127.0.0.1
port 6381
daemonize yes
pidfile /usr/local/redis/redis_6381.pid
loglevel notice
logfile /usr/local/redis/redis_6381.log
dir /usr/local/redis/data/
slaveof 127.0.0.1 6380
EOF
cat << EOF > /usr/local/redis/conf/redis6382.conf
bind 127.0.0.1
port 6382
daemonize yes
pidfile /usr/local/redis/redis_6382.pid
loglevel notice
logfile /usr/local/redis/redis_6382.log
dir /usr/local/redis/data/
slaveof 127.0.0.1 6380
EOF
  • 启动则完成主从复制架构的部署
redis-server /usr/local/redis/conf/redis6380.conf
redis-server /usr/local/redis/conf/redis6381.conf
redis-server /usr/local/redis/conf/redis6382.conf
  • 验证测试
127.0.0.1:6380> info Replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=1334,lag=1
slave1:ip=127.0.0.1,port=6382,state=online,offset=1334,lag=1
master_repl_offset:1334
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:1333
127.0.0.1:6380> set name yingges
OK
127.0.0.1:6380> exit
[root@node1 ~]# redis‐cli ‐p 6381
127.0.0.1:6381> get name
"yingges"
127.0.0.1:6381> set name2 redis
(error) READONLY You can't write against a read only slave.
  • 建议可以使用三台机器部署实验,ip地址分别改为新的地址,因为主从复制在一台机器上没有现实意义

架构–哨兵

  • Redis的主从复制模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用场景这种故障处理的方式是无法接受的。
  • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

工作原理

  • 每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在 指定时间( down-after-milliseconds项 )内未回应,则暂时认为对方已挂(主观宕机:sdown),若“哨兵群”中的多数 sentinel,都报告某一master没响应,系统才认为该master”彻底死亡”(即:客观上的真正down机:odown),通过一定的 vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置。
    在这里插入图片描述部署:
  • 部署哨兵1:监听26378端口
#!/bin/bash
cat << EOF > /usr/local/redis/conf/redis-sentinel26738.conf
port 26378
daemonize yes
dir "/tmp"
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
logfile "/usr/local/redis/log/sentinel.log.26378"
EOF
  • 配置哨兵2:监听26379端口
#!/bin/bash
cat << EOF > /usr/local/redis/conf/redis-sentinel26739.conf
port 26379
daemonize yes
dir "/tmp"
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
logfile "/usr/local/redis/log/sentinel.log.26379"
EOF
  • 启动哨兵服务
[root@master redis]# redis-sentinel /usr/local/redis/conf/redissentinel26739.conf
[root@master redis]# redis-sentinel /usr/local/redis/conf/redissentinel26738.conf
  • 通常情况下我们尽量启动3个哨兵(奇数)及以上监听一个主节点。
  • 验证测试
关闭master上redis服务
查看日志字段:
+switch‐master mymaster 127.0.0.1 6380 127.0.0.1 6382
master切换
重启旧master上redis服务
查看日志字段:
+convert‐to‐slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1
6382
成为slave
127.0.0.1:6382> info Replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=131255,lag=0
slave1:ip=127.0.0.1,port=6380,state=online,offset=131388,lag=0
master_repl_offset:131388
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:131387

架构–集群

  • redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很 浪费内存,所以在redis3.0上加入了cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容。
  • 优点
    • 将Redis的写操作分摊到了多个节点上,提高写的并发能力,扩容简单
  • 缺点
    • 每个Node承担着互相监听、高并发数据写入、高并发数据读出,工作任务繁重。

工作原理:

  • 对象保存到Redis之前先经过CRC16哈希到一个指定的Node上。
  • 每个Node被平均分配了一个Slot段,对应着0-16384,Slot不能重复也不能缺失,否则会导致对像重复存储或无法存储。
  • Node之间也互相监听,一旦有Node退出或者加入,会按照Slot为单位做数据的迁移。例如Node1如果掉线了,0- 5640这些Slot将会平均分摊到Node2和Node3上,由于Node2和Node3本身维护的Slot还会在自己身上不会被重新 分配,所以迁移过程中不会影响到5641-16384Slot段的使用。
    在这里插入图片描述部署:
  • 环境准备
#!/bin/bash
yum install gcc-c++ -y
wget http://download.redis.io/releases/redis‐5.0.4.tar.gz
tar xzf redis‐5.0.4.tar.gz
cd redis‐5.0.4
make install PREFIX=/usr/local/redis
PATH=$PATH:/usr/local/redis/bin
  • 部署
[root@node2 ~]# mkdir /usr/local/redis‐cluster
[root@node2 ~]# cd /usr/local/redis‐cluster/
[root@node2 redis‐cluster]# bash ‐x redis‐cluster.sh
#!/bin/bash
mkdir /usr/local/redis-cluster/redis{7000..7005} -pv
touch /usr/local/redis-cluster/redis{7000..7005}/redis.conf
#!/bin/bash
for i in {7000..7005};
do
cat << EOF > /usr/local/redis-cluster/redis$i/redis.conf
daemonize yes
port $i
cluster-enabled yes
cluster-config-file /usr/local/redis-cluster/redis$i/nodes-$i.conf
cluster-node-timeout 5000
appendonly yes
EOF
redis-server /usr/local/redis-cluster/redis$i/redis.conf
done
#检查各进程是否ok
[root@node2 local]# ps ‐ef | grep redis
root 5761 1 0 03:46 ? 00:00:00 redis‐server *:7000 [cluster]
root 5767 1 0 03:46 ? 00:00:00 redis‐server *:7001 [cluster]
root 5773 1 0 03:46 ? 00:00:00 redis‐server *:7002 [cluster]
root 5779 1 0 03:46 ? 00:00:00 redis‐server *:7003 [cluster]
root 5785 1 0 03:46 ? 00:00:00 redis‐server *:7004 [cluster]
root 5791 1 0 03:46 ? 00:00:00 redis‐server *:7005 [cluster]
[root@node2 local]# redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001
\
> 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
> --cluster-replicas 1
#输入yes,即按照此方式分配master和slave
M: 511ba9acbff21c59de7654342dc3847a9c9309d7 127.0.0.1:7000
slots:[05460] (5461 slots) master
M: fb3ee7237c0a1e164469f312b8fd65379139e6f0 127.0.0.1:7001
slots:[546110922] (5462 slots) master
M: 970f5bbc15256edbdd4587dda6dd4050dc6c651a 127.0.0.1:7002
slots:[1092316383] (5461 slots) master
S: 37bef4ed48428e9c530b5c963c3afc3975a7049b 127.0.0.1:7003
replicates fb3ee7237c0a1e164469f312b8fd65379139e6f0
S: fd4c06655852c01b5c850d438cf4eca71a101a70 127.0.0.1:7004
replicates 970f5bbc15256edbdd4587dda6dd4050dc6c651a
S: 86ef91e58e5736bcda38582d824242bbf74d2d25 127.0.0.1:7005
replicates 511ba9acbff21c59de7654342dc3847a9c9309d7
  • 验证测试
[root@node2 local]# redis‐cli ‐c ‐p 7000
#查询集群信息
127.0.0.1:7000> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:353
cluster_stats_messages_pong_sent:357
cluster_stats_messages_sent:710
cluster_stats_messages_ping_received:352
cluster_stats_messages_pong_received:353
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:710
#查询集群各节点
127.0.0.1:7000> cluster nodes
86ef91e58e5736bcda38582d824242bbf74d2d25 127.0.0.1:7005@17005 slave
511ba9acbff21c59de7654342dc3847a9c9309d7 0 1554278064038 6 connected
fd4c06655852c01b5c850d438cf4eca71a101a70 127.0.0.1:7004@17004 slave
970f5bbc15256edbdd4587dda6dd4050dc6c651a 0 1554278062005 5 connected
970f5bbc15256edbdd4587dda6dd4050dc6c651a 127.0.0.1:7002@17002 master ‐ 0
1554278063031 3
connected 1092316383
37bef4ed48428e9c530b5c963c3afc3975a7049b 127.0.0.1:7003@17003 slave
fb3ee7237c0a1e164469f312b8fd65379139e6f0 0 1554278062000 4 connected
fb3ee7237c0a1e164469f312b8fd65379139e6f0 127.0.0.1:7001@17001 master ‐ 0
1554278062529 2
connected 546110922
511ba9acbff21c59de7654342dc3847a9c9309d7 127.0.0.1:7000@17000 myself,master
‐ 0
1554278063000 1 connected 05460
[root@node2 local]# redis‐cli -c -p 7000
127.0.0.1:7000> set name eagles
‐> Redirected to slot [5798] located at 127.0.0.1:7001
OK # 数据分配特性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值