数据库
首页 > 数据库> > Redis记录,未完待续!

Redis记录,未完待续!

作者:互联网

Redis

安装使用redis

1.需要安装gcc

yum -y install gcc autoconf libtool make
yum install gcc-c++
yum install centos-release-scl scl-utils-build //安装scl源
yum list all --enablerepo='centos-sclo-rh'   //列出scl可用源
yum install -y devtoolset-8-toolchain  
scl enable devtoolset-8 bash
gcc --version  //查看gcc版本
#运行时出现yum.pid被锁定时 执行
rm -f /vat/run/yum.pid

2.解压好redis压缩包后,进入文件夹编译程序

make  //编译
make install PREFIX=/usr/local/redis   //安装

whereis redis //查看redis安装路径
    
//前台启动   
cd /usr/local/redis/bin/
./redis-server  //启动
//后台启动
mv /root/redis-6.0.6/redis.conf /usr/local/redis  //移动配置文件
./bin/redis-server ./redis.conf  //使用配置文件启动

#查看是否启动成功了,查看进程
ps -ef |grep redis
ps aux| grep redis

3.redis关闭

./redis-cli shutdown   //正常停止redis-server 正常关闭服务端  --> 数据不会丢失
//如果设置的有密码 ./redis-cli shutdown 此命令无效,需要进入客户端在输入shutdown 
kill -9 服务号 //强制关闭 --> 数据会丢失
//redis安装目录下
./bin/redis-server ./redis.conf   //使用配置文件启动
./bin/redis-cli -h []ip地址] -p [端口号] -a [密码]
连接redis server
[root@VM_0_4_centos bin]# ./redis-cli -p 6379

Redis命令

基础通用命令
keys [key]	//查找匹配的key 
keys * 		//查找所有key;
del	[key]	//删除key?1:0;
dump [key]	//获取key的序列化值;
exists [key]//判断key是否存在?1:0;
expire [key] seconds	//设置key的存活时间seconds/秒 ?1:0;
ttl [key] 	//key的存活时间;返回剩时间、返回-1(默认永久生效)、返回-2(无效)
pexpire [key] milliseconds	//设置key 的存活时间 milliseconds/毫秒 ?1:0;
pttl [key] 	//key的存活时间;返回剩时间、返回-1(默认永久生效)、返回-2(无效)
//--  expire 和 pexpire 设置的时间可以相互覆盖最新为准 --
//--  ttl 和 pttl 获取的时间可以都是相同的只是单位不同 --
persist [key]	//移除key的过期时间,永久生效?1:0
//-- redis 默认支持16个数据库, 有唯一标识代表,0~15
select 0	//选择数据库

rename a/[old] b/[new]	//修改key 名字--> 把a改为b;
move c[key] 1[库]	//把c移动到库1中 ?1:0;
type [key]	//返回key的类型

//--
FLUSHDB 	//删除当前数据库的所有key
FLUSHALL 	//删除所有数据库的所有key
DBSIZE 		//返回当前数据库的 key 的数量
TIME 		//返回当前服务器时间
ROLE 		//返回主从实例所属的角色
SAVE 		//异步保存数据到硬盘
CLIENT LIST //获取连接到服务器的客户端连接列表
CONFIG REWRITE //对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写
CONFIG SET parameter value //修改 redis 配置参数,无需重启
CONFIG RESETSTAT //重置 INFO 命令中的某些统计数据

String数据类型

二进制安全, 一个key 最大存储512MB执行效率高,不需要频繁的编解码,不会出现乱码;

//-- key 区分大小写 value可以被覆盖,无视类型 --
set info:msg 活动时间 //设置一个string类型的key
get [key] //获取一个指定的key值,如果key不存在 返回 nil
mset [key] [value] [key value ...] //同时设置一个或多个k-v对
mget [key] [key  ...] //同时获取一个或多个k-v对
setnx [key] [value] //只有key不存在时才设置值? 1:0;
setex data 30 "hello" //设置过期时间
getset [key] [value] //返回旧值,并设置新值  如果替换一个有期限的那么这个值就会变永久
del info:Hello info:1 info:3  //一次删除多个 key
//--
getrange [key] 0/[start] 3/[end] //截取0到3 共4个字符串
strlen [key] //获取key的长度
incr [key] //加1 ,如果该key不存在,创建并在0的基础上加1,返回加1
decr [key] //减一 ,返回值都是当前家减后的值
incrby [key] [var]  //加减var 变量--》10 没运行一次就加减10
decrby [key] [var]
//----incr和decr的改变不会对过期时间有影响; 其他的如set,getset等改变属性值都会对过期时间有影响
Hash数据类型

是一个string 类型的field和value的映射表,hash 特别适合用于存储对象,redis中每个hash 可以存储40多亿的键值对;

hset [key] [field] [value] //设置一个hash 类型
hset bean1 name zhangsan  //设置一个属性值  
hmset bean2 id 1 name zhangsan age 13 //一次设置多个
hset && hmset 虽然都能设置多个属性,但前者是多次执行(返回设置属性数量),后者是一次执行(返回ok)

hget bean1 name //获取属性值
hmget bean2 id name  //获取多个属性值
查看hash所有的值()
hgetall bean2 //获取所有 属性名-属性值   
hkeys [key] //获取所有哈希表中的字段  即获取所有 属性值

hlen [key]  //获取哈希表中字段的数量
hdel [key] [属性名字...] //一个或多个属性
hsetnx [key] [field] [value] //当这个key不存在时:设置一个hash 类型
hincrby [key] [属性] [var] //把key 的属性值 增加 var 整数
hincrbyfloat [key] [属性] [var] //把key 的属性值 增加 var 浮点数值
hexists [key] [属性] //属性是否存在 存在--1;不存在--0;
hvals hashs //获取所有hashs的value值
hkeys hashs //获取所有hashs的key属性名
hsetnx hashs adree hee //当hashs的 adree 属性不存在时创建
Set数据类型

String 类型的无序集合,集合成员是唯一的,这就意味着集合中不能出现重复的数据;Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1);

集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员);

sadd key member      //可以添加一个或多个元素,返回值:添加元素的个数
scard key            //查key 元素的个数
smembers key         //返回所有的元素
sdiff key            //sdiff key1 key2 keyn 返回多个集合的差集(交集是sinter,并集是sunion)
sismember key member //判断 member 元素是否是集合 key 的成员?1:0
srem key member      //移除集合中一个或多个成员 ?1:0
sscan key cursor     //迭代集合中的元素
list数据类型

有序链表,可重复,先入的在后面 下标最大,新入的在左边下标最小

下标 0 1 2 3 4 5 6 7 8 9

元素 1 2 3 4 5 6 7 8 9 10

//添加元素
lpush listdata value   //从左开始 也就是0下标开始
rpush listdata value   //从右开始 也就是最大的下标开始
lset key index value 
//查看元素
lindex listdata index //返回索引为index的值
lrange listdata 0 -1   //左数从0开始,右数从-1开始,这是查看全部; 0 0 查看第一个 。。。
//删除元素
lpop listdata          //返回并删除链表头元素
rpop listdata          //返回并删除链表尾部元素
lrem listdata count value  //删除count个与value相同的值
    count > 0 : //从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
    count < 0 : //从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
    count = 0 : //移除表中所有与 VALUE 相等的值。
    lrem listdata 1 10  //从左到右,即表头到表尾,即 最小的下标到最大的下标
    lrem listdata -1 10 //反之
    lrem listdata 0 10  //把元素为10 的全删除了
ltrim key start end //只保留在[start,end]区间的数,其余的删除
lset listdata 0 1  //修改listdata 第0个的值为1
lpushx listdata element //为已经存在的list再表头添加元素
rpushx listdata element //为已经存在的list再表尾添加元素
llen listdata //获取元素的长度

zset(sorted set)

有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

zadd
zcard
zcount 
zincrby 
zrange zset 0 -1
zrangebylex //通过字典区间返回有序集合的成员
zrangebyscore //通过分数返回有序集合指定区间内的成员
zrank 	//返回有序集合中指定成员的索引
zrem 	//移除有序集合中的一个或多个成员
zremrangebylex //移除有序集合中给定的字典区间的所有成员
zremrangebyscore	//移除有序集合中给定的分数区间的所有成员
zrevrange //返回有序集中指定区间内的成员,通过索引,分数从高到底
zrevrangebyscore	//返回有序集中指定分数区间内的成员,分数从高到低排序
zrevrank 	//返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
zscore	//返回有序集中,成员的分数值
zscan //迭代有序集合中的元素
ZADD key score1 member1 [score2 member2] //向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZCARD key	// 获取有序集合的成员数
ZCOUNT key min max //计算在有序集合中指定区间分数的成员数
ZINCRBY key increment member //有序集合中对指定成员的分数加上增量 increment
ZINTERSTORE destination numkeys key [key ...] //计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
ZLEXCOUNT key min max //在有序集合中计算指定字典区间内成员数量
ZRANGE key start stop [WITHSCORES] //通过索引区间返回有序集合成指定区间内的成员
ZRANGEBYLEX key min max [LIMIT offset count] //通过字典区间返回有序集合的成员
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] //通过分数返回有序集合指定区间内的成员
ZRANK key member //返回有序集合中指定成员的索引
ZREM key member [member ...] //移除有序集合中的一个或多个成员
ZREMRANGEBYLEX key min max //移除有序集合中给定的字典区间的所有成员
ZREMRANGEBYRANK key start stop //移除有序集合中给定的排名区间的所有成员
ZREMRANGEBYSCORE key min max //移除有序集合中给定的分数区间的所有成员
ZREVRANGE key start stop [WITHSCORES] //返回有序集中指定区间内的成员,通过索引,分数从高到底
ZREVRANGEBYSCORE key max min [WITHSCORES] //返回有序集中指定分数区间内的成员,分数从高到低排序
ZREVRANK key member //返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
ZSCORE key member //返回有序集中,成员的分数值
ZUNIONSTORE destination numkeys key [key ...] //计算给定的一个或多个有序集的并集,并存储在新的 key 中
ZSCAN key cursor [MATCH pattern] [COUNT count] //迭代有序集合中的元素(包括元素成员和元素分值)

HyperLogLog

HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

1[PFADD key element element …] 添加指定元素到 HyperLogLog 中。
2[PFCOUNT key key …] 返回给定 HyperLogLog 的基数估算值。
3[PFMERGE destkey sourcekey sourcekey …] 将多个 HyperLogLog 合并为一个 HyperLogLog
pfmerge HyperLogLog hylog hylogg	//将多个 HyperLogLog 合并为一个 HyperLogLog
pfadd hylog 1 2 3 	//添加指定元素到 HyperLogLog 中
pfcount hylog		//返回给定 HyperLogLog 的基数估算值

redis配置文件

daemonize 如果需要将Redis服务以守护进程在后台运行,则把该项的值改为yes
pidfile 配置多个pid的地址,默认在/var/run/redis/pid
bind 绑定ip,设置后只接受来自该ip的请求
port 监听端口,默认是6379
timeout 客户端连接超时的设定,单位是秒
loglevel 分为4级,debug、verbose、notice、warning
logfile 配置log文件地址
databases 设置数据库的个数,默认使用的数据库为0
save 设置redis进行数据库镜像的频率
rdbcompression 在进行镜像备份时,是否进行压缩
Dbfilename 镜像备份文件的文件名
Dir 数据库镜像备份文件的存放路径
Slaveof 设置数据库为其他数据库的从数据库
Masterauth 主数据库连接需要的密码验证
Requirepass 设置登录时,需要使用的密码
Maxclients 设置同时连接的最大客户端数量
Maxmemory 设置redis能够使用的最大内存
Appendonly 开启append only模式
Appendfsync 设置对appendonly.aof文件同步的频率
vm-enabled 是否开启虚拟内存支持
vm-swap-file 设置虚拟内存的交换文件路径
vm-max-memory 设置redis能够使用的最大虚拟内存
vm-page-size 设置虚拟内存的页大小
vm-pages 设置交换文件的总的page数量
vm-max-threads 设置VMIO同时使用的线程数量
Glueoutputbuf 把小的输出缓存存放在一起
hash-max-zipmap-entries 设置hash的临界值
Activerehashing 重新hash
bind 127.0.0.1    //绑定当前主机访问,不允许其他访问(注释即可)
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes    //是否开启后台运行
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
requirepass smxr     //启用密码配置:smxr
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

主从复制

只配置从库,不配置主库(默认每个redis都是一个主库)

127.0.0.1:6379> info replication  //查看当前库的信息
# Replication 
role:master  //角色 master
connected_slaves:0  //没有从机 
master_replid:8d54e8c91f682aa20addc3f8bae3d97984e214f2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
//修改配置文件redis.conf配置文件
实例端口号:		 port 6379
实例进程名字:		pidfile /var/run/redis_6379.pid
实例日志文件名字: logfile ""
持久化数据文件名: dbfilename dump.rdb  
//同一台主机上要不能重复,负责就会覆盖日志,不同主机可以
slaveof 39.103.178.68 6379  //关联主机39.103.178.68端口6379  认主机做主人
//从服务器现有的数据会先被清空,然后才会同步主服务器的数据。 
replicaof <masterip> <masterport>  //此命令同样可以
//上面的两个命令会在redis实例重启后失效
//直接修改配置文件可以实现开机自动挂载
// vim ./redis.conf
replicaof 39.103.178.68 6379  
masterauth smxr  //主机密码
 //查看是否成功 
info replication  
//------从机-----
role:slave
master_host:39.103.178.68
master_port:6379
master_link_status:down  //主机为挂载(因为master有密码),正常为: up
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1615630951
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8d54e8c91f682aa20addc3f8bae3d97984e214f2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
//--------主机-------
role:master  
connected_slaves:1
slave0:ip=49.232.9.92,port=6379,state=online,offset=182,lag=1
master_replid:de4483628fbe7c6ade403d8fbd9cd4daa2baaf7e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:182
**************从机是不能写入的,只能读取***************
测试: master断开连接,slave依旧是连接主机的,但是slave不能写入只能读取
	  master恢复后正常读写;
      slave断开连接,如果没有配置文件配置,slave就会变回主机;只有配置了就会自动同步;
主机断开如何手动变更slave为master
    slaveof no one   //slave为master
复制原理

slave启动成功连接到master之后会发送一个sync命令即同步;

master接收到命令后,启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后将文件整个发送到slave,并完成一次完全同步;

全量复制:而slave服务在接收到新的数据库文件数据后,将其存盘并加载到内存中;

增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步;

​ 但是只要是重新连接master,就会执行一次完全同步即全量复制;

哨兵模式

redis-sentinel.conf配置文件内容(26379默认端口)

sentinel  monitor 被监控的名称  host  port  1 
sentinel monitor myredis  192.168.15.133  6379  1
sentinel auth-pass mymaster redis007  //有密码的需要验证
//1、使用时不能用127.0.0.1,需要用真实IP,不然java程序通过哨兵会连到java程序所在的机器(127.0.0.1 )
//2、配置哨兵监控一个系统时,只需要配置其监控主数据库即可,哨兵会自动发现所有复制该主数据库的从数据库
----------------------------------------------
 nohup ./bin/redis-sentinel ./sentinel.conf &
 //后台启动发现
----  redis-sentinel.conf 编译后的  --------------
protected-mode no
port 26379
user default on nopass ~* +@all
dir "/usr/local/redis"
sentinel deny-scripts-reconfig yes
sentinel monitor myredis 39.103.178.68 6379 1
sentinel auth-pass myredis smxr
sentinel config-epoch myredis 0
sentinel leader-epoch myredis 2
sentinel current-epoch 2

//常用命令
config get master  //查看节点配置的主要节点用户
config set masterauth xxxx //配置主节点用户密码

    
//配置文件:
//端口
port 26379
//后台启动
daemonize yes
//运行时PID文件
pidfile /var/run/redis-sentinel.pid
//日志文件(绝对路径)
logfile "/opt/app/redis6/sentinel.log"
//数据目录
dir /tmp/sentinel_26379
//监控的节点名字可以自定义,后边的2代表的:如果有俩个哨兵判断这个主节点挂了那这个主节点就挂了,通常设置为哨兵个数一半加一
sentinel monitor mymaster 127.0.0.1 6379 2
//哨兵连接主节点多长时间没有响应就代表主节点挂了,单位毫秒。默认30000毫秒,30秒
sentinel down-after-milliseconds mymaster 30000
//在故障转移时,最多有多少从节点对新的主节点进行同步。这个值越小完成故障转移的时间就越长,这个值越大就意味着越多的从节点因为同步数据而暂时阻塞不可用
sentinel parallel-syncs mymaster 1
//在进行同步的过程中,多长时间完成算有效,单位是毫秒,默认值是180000毫秒,3分钟。
sentinel failover-timeout mymaster 180000
//禁止使用SENTINEL SET设置notification-script和client-reconfig-scriptsentinel
deny-scripts-reconfig yes
//启动
[root@smxr redis]# ./bin/redis-sentinel ./redis-sentinel.conf 
7403:X 14 Mar 2021 23:41:31.917 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
7403:X 14 Mar 2021 23:41:31.917 # Redis version=6.0.6, bits=64, commit=00000000, modified=0, pid=7403, just started
7403:X 14 Mar 2021 23:41:31.917 # Configuration loaded
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.0.6 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 7403
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

7403:X 14 Mar 2021 23:41:31.919 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
7403:X 14 Mar 2021 23:41:31.922 # Sentinel ID is cdf12b90adad3b5c7ee638d95633bc21b817f277
7403:X 14 Mar 2021 23:41:31.922 # +monitor master myredis 39.103.178.68 6379 quorum 1

//上面的没有配置密码所以是cannot

[root@smxr redis]# ./bin/redis-sentinel ./redis-sentinel.conf 
29532:X 15 Mar 2021 23:27:13.623 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
29532:X 15 Mar 2021 23:27:13.623 # Redis version=6.0.6, bits=64, commit=00000000, modified=0, pid=29532, just started
29532:X 15 Mar 2021 23:27:13.623 # Configuration loaded
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.0.6 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 29532
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

29532:X 15 Mar 2021 23:27:13.624 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
//警告描述:不能设置tcp的堆积为511,因为/proc/sys/net/core/somaxconn的值为128太低
29532:X 15 Mar 2021 23:27:13.624 # Sentinel ID is cdf12b90adad3b5c7ee638d95633bc21b817f277
29532:X 15 Mar 2021 23:27:13.624 # +monitor master myredis 39.103.178.68 6379 quorum 1
29532:X 15 Mar 2021 23:27:13.627 * +slave slave 49.232.9.92:6379 49.232.9.92 6379 @ myredis 39.103.178.68 6379
29532:X 15 Mar 2021 23:27:13.630 * +slave slave 49.232.9.92:6380 49.232.9.92 6380 @ myredis 39.103.178.68 6379

//还是连接失败cannot
//echo 511 > /proc/sys/net/core/somaxconn  临时解决办法
//解决办法 vim /etc/sysctl.conf
vm.swappiness = 0
net.ipv4.neigh.default.gc_stale_time = 120

# see details in https://help.aliyun.com/knowledge_detail/39428.html
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.accept_source_route = 1   //添加这个

# see details in https://help.aliyun.com/knowledge_detail/41334.html
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 1024
net.ipv4.tcp_synack_retries = 2

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
kernel.sysrq = 1
//此方法需要重启服务器,所以使用了临时的解决办法
12775:X 15 Mar 2021 23:42:03.175 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
12775:X 15 Mar 2021 23:42:03.175 # Redis version=6.0.6, bits=64, commit=00000000, modified=0, pid=12775, just started
12775:X 15 Mar 2021 23:42:03.175 # Configuration loaded
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.0.6 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 12775
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

12775:X 15 Mar 2021 23:42:03.176 # Sentinel ID is cdf12b90adad3b5c7ee638d95633bc21b817f277
12775:X 15 Mar 2021 23:42:03.176 # +monitor master myredis 39.103.178.68 6379 quorum 1
//启动成功
//当前master状态  (退出主机观察)
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=49.232.9.92,port=6379,state=online,offset=9544565,lag=0
slave1:ip=49.232.9.92,port=6380,state=online,offset=9544565,lag=0
master_replid:cc371bd8563c891281297b855459940e62134a4b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:9544565
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:8495990
repl_backlog_histlen:1048576
Master宕机后
12775:X 15 Mar 2021 23:42:03.176 # Sentinel ID is cdf12b90adad3b5c7ee638d95633bc21b817f277
12775:X 15 Mar 2021 23:42:03.176 # +monitor master myredis 39.103.178.68 6379 quorum 1
12775:X 15 Mar 2021 23:46:14.976 # +sdown master myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:14.976 # +odown master myredis 39.103.178.68 6379 #quorum 1/1
12775:X 15 Mar 2021 23:46:14.976 # +new-epoch 3
12775:X 15 Mar 2021 23:46:14.976 # +try-failover master myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:14.978 # +vote-for-leader cdf12b90adad3b5c7ee638d95633bc21b817f277 3
12775:X 15 Mar 2021 23:46:14.978 # +elected-leader master myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:14.978 # +failover-state-select-slave master myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:15.044 # +selected-slave slave 49.232.9.92:6379 49.232.9.92 6379 @ myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:15.044 * +failover-state-send-slaveof-noone slave 49.232.9.92:6379 49.232.9.92 6379 @ myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:15.144 * +failover-state-wait-promotion slave 49.232.9.92:6379 49.232.9.92 6379 @ myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:15.157 # +promoted-slave slave 49.232.9.92:6379 49.232.9.92 6379 @ myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:15.157 # +failover-state-reconf-slaves master myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:15.202 * +slave-reconf-sent slave 49.232.9.92:6380 49.232.9.92 6380 @ myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:16.237 * +slave-reconf-inprog slave 49.232.9.92:6380 49.232.9.92 6380 @ myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:16.237 * +slave-reconf-done slave 49.232.9.92:6380 49.232.9.92 6380 @ myredis 39.103.178.68 6379
12775:X 15 Mar 2021 23:46:16.304 # +failover-end master myredis 39.103.178.68 6379
								//选择一个master
12775:X 15 Mar 2021 23:46:16.304 # +switch-master myredis 39.103.178.68 6379 49.232.9.92 6379
12775:X 15 Mar 2021 23:46:16.304 * +slave slave 49.232.9.92:6380 49.232.9.92 6380 @ myredis 49.232.9.92 6379
12775:X 15 Mar 2021 23:46:16.304 * +slave slave 39.103.178.68:6379 39.103.178.68 6379 @ myredis 49.232.9.92 6379		// 39.103.178.68:6379 变成了slave并且sdown
12775:X 15 Mar 2021 23:46:46.346 # +sdown slave 39.103.178.68:6379 39.103.178.68 6379 @ myredis 49.232.9.92 6379
12775:X 15 Mar 2021 23:52:43.806 # -sdown slave 39.103.178.68:6379 39.103.178.68 6379 @ myredis 49.232.9.92 6379		//监听到上线
12775:X 15 Mar 2021 23:52:53.725 * +convert-to-slave slave 39.103.178.68:6379 39.103.178.68 6379 @ myredis 49.232.9.92 6379
//最后上线了但没有办法作为slave连接到master
master恢复后无法作为slave上线

因为master离线后再次启动时需要配置文件slave相关的配置,如果还是原先的配置没有设置密码还好,如果设置了密码就需要再配置文件里加上了;
上面的无法恢复就是因为设置了密码,导致master恢复后无法作为slave上线

Redis集群

//安装运行环境 要求ruby版本>2.3
yum install ruby
ruby -v  //查看ruby版本
//---------安装过程----------
// 安装ruby,rubygems插件
yum -y install ruby rubygems
// 升级ruby版本
// 安装yum源
yum install -y centos-release-scl-rh
// 安装指定版本的ruby,这里安装2.3版本
yum install -y rh-ruby23
// 生效升级后的配置
scl enable rh-ruby23 bash
// 查看升级后的版本
ruby -v

//安装运行环境 要求gcc版本>5.0
gcc -v    //查看gcc版本
//升级到gcc 9.3:
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
//需要注意的是scl命令启用只是临时的,退出shell或重启就会恢复原系统gcc版本。(不建议使用)
scl enable devtoolset-9 bash

搭建步骤:

  1. 启动节点:将节点以集群方式启动,此时节点是独立的。
  2. 节点握手:将独立的节点连成网络。
  3. 槽指派:将16384个槽位分配给主节点,以达到分片保存数据库键值对的效果。
  4. 主从复制:为从节点指定主节点。
  5. https://blog.csdn.net/yanziyu0721730/article/details/112602134
  6. https://blog.csdn.net/weixin_39338423/article/details/108663614
//开启服务器端口
[root@smxr redis]# firewall-cmd --zone=public --add-port=6900/tcp --permanent
success
[root@smxr redis]# firewall-cmd --zone=public --add-port=6901/tcp --permanent
success
[root@smxr redis]# firewall-cmd --zone=public --add-port=6902/tcp --permanent
success
[root@smxr redis]# firewall-cmd --reload
success
[root@smxr redis]# firewall-cmd --list-port
80/tcp 8080/tcp 2306/tcp 6379/tcp 6900/tcp 6901/tcp 6902/tcp
//三主三从 --> 一台三个主实例,一台三个从实例
//配置文件修改
port  xxx //实际修改
bind 0.0.0.0 //实际修改,注释掉任意可以访问
dbfilename "dump6900.rdb"  //备份文件名
# masterauth xxx //先注释掉后面再添加
# requirepass liu.150938  //先注释掉后面再添加
logfile "6900.log" //日志文件
pidfile "/var/run/redis_6900.pid" //线程
daemonize yes  //后台运行
cluster-enabled yes  //开启集群模式
cluster-node-timeout 15000 //超时设置(毫秒)
cluster-config-file node-7000.conf  // 集群配置文件,redis首次启动时会在redis.conf所在的文件夹下自动创建该文件,注意这里的node-7000.conf要根据实例启动的端口号自行修改

//创建好配置文件后启动这6个实例  --可以使用脚本启动
//集群启动命令
//使用create命令 --replicas 1 参数表示为每个主节点创建一个从节点,其他参数是实例的地址集合.
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

./redis-cli --cluster create 39.103.178.68:6900 39.103.178.68:6901 39.103.178.68:6902 49.232.9.92:6900 49.232.9.92:6901 49.232.9.92:6902 --cluster-replicas 1

主从、哨兵、集群、的区别

master slave
主不用配置,从redis的conf文件加入 slaveof ip port 就可以了
或者从redis启动时 redis-server --port 6380 --slaveof 127.0.0.1 6379
从数据库一般是只读,可以改为可写,但写入的数据很容易被主同步没,所以还是只读就可以。
也可以在运行是使用slaveof ip port命令,停止原来的主,切换成刚刚设置的主 slaveof no one会把自己变成主

哨兵模式:当主数据库遇到异常中断服务后,开发者可以通过手动的方式选择一个从数据库来升格为主数据库,以使得系统能够继续提供服务。然而整个过程相对麻烦且需要人工介入,难以实现自动化所以有了哨兵模式;
作用:
监控:监控主数据库和从数据库是否正常运行;
通知:当监控节点出现故障,哨兵之间进行通讯。
自动故障转移:主数据库出现故障时自动将从数据库转换为主数据库;
注意:
1、使用时不能用127.0.0.1,需要用真实IP,不然java程序通过哨兵会连到java程序所在的机器;

​ 2、配置哨兵监控一个系统时,只需要配置其监控主数据库即可,哨兵会自动发现所有复制该主数据库的从数据库;
切换过程:
​ slave leader升级为master;
​ 其他slave修改为新master的slave;
​ 客户端修改连接;
​ 老的master如果重启成功,变为新master的slave;

集群模式:
redis是一个开源的key value存储系统,受到了广大互联网公司的青睐。redis3.0版本之前只支持单例模式,在3.0版本及以后才支持集群,我这里用的是redis3.0.0版本;
redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;
redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;
为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;
那么如何判断集群是否挂了呢? -> 如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;
那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢? -> 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。
综上所述,每个Redis集群理论上最多可以有16384个节点。

Redis集群至少需要3个节点,因为投票容错机制要求超过半数节点认为某个节点挂了该节点才是挂了,所以2个节点无法构成集群。

要保证集群的高可用,需要每个节点都有从节点,也就是备份节点,所以Redis集群至少需要6台服务器。因为我没有那么多服务器,也启动不了那么多虚拟机,所在这里搭建的是伪分布式集群,即一台服务器虚拟运行6个redis实例,修改端口号为(7001-7006)

Redis缓存穿透和雪崩

发布订阅

127.0.0.1:6379> subscribe redisChat		//创建频道redisChat 
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1		//1创建成功,0失败
1) "message"
2) "redisChat"
3) "Redis is a great caching technique"
1) "message"
2) "redisChat"
3) "Learn redis by www.smxr.com"
127.0.0.1:6379> publish redisChat "Learn redis by www.smxr.com"	//订阅频道redisChat 发送消息
(integer) 1		//发送成功
(integer) 2		//当使用subscribe redisChat再次创建并发送指令返回2,新的和之前的都可以收到消息;
127.0.0.1:6379> 
subscribe redisChat		//创建频道redisChat 
publish redisChat "Learn redis by www.smxr.com"	//订阅频道redisChat 发送消息
psubscribe [pattern...]	//订阅一个或多个符合给定模式的频道。
PUBSUB subcommand [argument [argument ...]] //查看订阅与发布系统状态。
PUBLISH channel message 	//将信息发送到指定的频道
PUNSUBSCRIBE [pattern [pattern ...]] //退订所有给定模式的频道。
SUBSCRIBE channel [channel ...] //订阅给定的一个或多个频道的信息
UNSUBSCRIBE [channel [channel ...]] //指退订给定的频道。

数据保存和恢复

-- 
save	//该命令将在 redis 安装目录中创建dump.rdb文件
redis 127.0.0.1:6379> SAVE
--

恢复数据:如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可

获取 redis 目录可以使用 **CONFIG** 命令
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/redis"

创建 redis 备份文件也可以使用命令 BGSAVE,该命令在后台执行

127.0.0.1:6379> BGSAVE
Background saving started

测试(bin目录下的配置文件)

  1. redis-benchmark [option] [option value]
./redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 100000 -q
	//下面的是需要验证密码的;
./redis-benchmark -h 127.0.0.1 -p 6379 -a smxr -t set,lpush -n 100000 -q
//--测试 2核2G云服务
SET: 75471.70 requests per second
LPUSH: 77700.08 requests per second
//--单核2G云服务
SET: 47984.64 requests per second
LPUSH: 47303.69 requests per second

测试会在redis中保存对于的测试数据,别忘了删除

以上实例中主机为 127.0.0.1,端口号为 6379,执行的命令为 set,lpush,请求数为 10000,通过 -q 参数让结果只显示每秒执行的请求数。

序号选项描述默认值
1-h指定服务器主机名127.0.0.1
2-p指定服务器端口6379
3-s指定服务器 socket
4-c指定并发连接数50
5-n指定请求数10000
6-d以字节的形式指定 SET/GET 值的数据大小2
7-k1=keep alive 0=reconnect1
8-rSET/GET/INCR 使用随机 key, SADD 使用随机值
9-P通过管道传输 <numreq> 请求1
10-q强制退出 redis。仅显示 query/sec 值
11–csv以 CSV 格式输出
12-l生成循环,永久执行测试
13-t仅运行以逗号分隔的测试命令列表。
14-IIdle 模式。仅打开 N 个 idle 连接并等待。

中文乱码问题

如果是客户端启动:./redis-cli -p 6379 -a smxr --raw
如果是代码内启动:改变encoding编码集

键值设计

key名设计:

建议: 可读性和可管理性;
以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id;

ugc:video:1

value名设计:

强制:拒绝bigkey(防止网卡流量、慢查询);

string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000;

非字符串的bigkey,不要使用del删除,使用hscan、sscan、zscan方式渐进式删除,同时要注意防止bigkey过期时间自动删除问题(例如一个200万的zset设置1小时过期,会触发del操作,造成阻塞,而且该操作不会不出现在慢查询中(latency可查)),

ugc:video:1

建议使用expire设置过期时间(条件允许可以打散过期时间,防止集中过期),不过期的数据重点关注idletime。

例如hgetall、lrange、smembers、zrange、sinter等并非不能使用,但是需要明确N的值。有遍历的需求可以使用hscan、sscan、zscan代替。

禁止线上使用keys、flushall、flushdb等,通过redis的rename机制禁掉命令,或者使用scan的方式渐进式处理。

redis的多数据库较弱,使用数字进行区分,很多客户端支持较差,同时多业务用多数据库实际还是单线程处理,会有干扰。

原生命令:例如mget、mset。
非原生命令:可以使用pipeline提高效率。
使用批量操作提高效率
但要注意控制一次批量操作的元素个数(例如500以内,实际也和元素字节数有关)。

原生是原子操作,pipeline是非原子操作。
pipeline可以打包不同的命令,原生做不到
pipeline需要客户端和服务端同时支持。

Redis事务功能较弱,不建议过多使用

Redis使用场景

计数器

缓存

会话缓存

全页缓存(FPC)

查找表

消息队列(发布/订阅功能)

分布式锁实现

访问统计

标签:记录,Redis,-._,redis,未完待续,6379,master,key,_.-
来源: https://blog.csdn.net/qq_44738044/article/details/115351411