Redis-Linux-高级

手动分槽参考https://blog.csdn.net/weixin_40960410/article/details/106166582/

 

上一篇:https://www.cnblogs.com/abiu/p/13440919.html  的redis 基础知识已经看完了以后,就可以接着看这篇文章了

打开Linux 命令窗口,使用root权限,然后下载redis 的压缩包,这里下载4.0.0 版本的,

redis 是C 语言写的,要先确定 虚拟机安装有 gcc 没有的话下载安装: yum install gcc 

 步骤:

1、先  cd /   切换到 根目录

2、输入命令: wget http://download.redis.io/releases/redis-4.0.0.tar.gz 

3、然后解压: tar zxvf redis-4.0.0.tar.gz  

4、进入解压好的文件夹里: cd redis-4.0.0 

  // 可以先看看系统默认安装目录,和redis 要安装到的目录 cat Makefile

  // 编译:make

5、可以直接编译 并安装: make install 

6、 安装完以后, cd src   进到里面的src 目录,然后ll 可以看到安装好的redis 

7、 redis-server   直接回车,就启动了redis

8、 启动以后,就不用管了,再复制一个会话,打开客户端去连服务端 试试:

正常使用,连接成功

 

如果要启动多台redis 解决办法:src的redis 安装目录 下执行命令: redis-server --port 6380   回车

这样redis 的端口就变成6380 了,再去用客户端连接就会失败,要连接的是: redis-cli -p 6380   就能连接成功了

上面两种方式不推荐,一般在企业里启动的是

先  cd redis-4.0.0  目录下,找到一个redis.conf 的redis 配置文件,

然后输入命令: cat redis.conf | grep -v "#" |grep -v "^$" > redis-6379.conf 

就是复制一份redis.conf ,取名redis-6379.conf ,当然,都在在同一目录下,然后编辑这个redis-6379.conf 文件,只留下:

port 6379
daemonize yes
logfile "6379.log"
dir /redis-4.0.0/data

中间出错的话,就先提前在redis-4.0.0 目录下新建一个data ,然后再 保存这个redis-6379.conf 文件

然后就可以输出命令: redis-server redis-6379.conf    启动redis 服务

           redis-cli     启动客户端小试一下

redis 的安装目录下应该再见一个文件夹 conf ,不然以后要起多个redis 服务,岂不是好多的配置文件,太乱了:

使用命令: mkdir conf   新建一个conf 目录

然后把这个 6379 的配置文件剪切到 conf 目录里: mv redis-6379.conf conf 

这样的话,启动redis 服务命令是: redis-server conf/redis-6379.conf 

启动多个redis 服务:

先  cd conf   到conf 目录下,然后: cp redis-6379.conf redis-6380.conf    复制一个6379 的文件 6380

然后  vim redis-6380.conf   编写6380 的配置:

只需要改这些,然后保存退出就可以了,这样的话   redis-server conf/redis-6380.conf   就启动了

客户端启动的话, redis-cli -p [端口号]   指定端口号

         redis-cli -h [IP地址]   指定IP地址

 

持久化

RDB:快照方式,执行一次命令,就保存一次  

执行保存命令: save   每次set 数据时候每保存一次,就会再那个data 文件里的rdb 文件生出一条信息,要手动执行的。。

比如要设置 6379 这个端口的rdb 文件保存,先去把 redis-6379.conf 这个文件编写一下:

然后就可以正常使用了,比如这个 dump-6379.rdb 文件会在data 目录下生成,

这样就把数据持久化了,比如把6379 的这个服务的内存清除,然后重新启动6379 这个端口,

然后去客户端一样能查询之前保存过的数据,因为当6379 重新启动时候,数据就已经被加载了

save 指令的工作原理

当多个客户端 访问服务 时候,是有先后顺序的,因为redis 是单线程的,这样就类似于消息队列那种的吧。。。

如果有一个save 指定执行过长,其他客户端就会等着这个 save 指令,

所以线上环境不建议使用save 指令,因为会很拉低服务器的性能,可能造成严重的阻塞!

解决方法:bgsave 指令:手动启动后台保存操作,但不是立即执行的

bgsave 使用:一样是在客户端操作,比如set 完数据然后就 bgsave ,然后会给提示信息:Background saving started   后台执行, save 是马上执行,

bgsave 执行原理

自动执行持久化命令:

 

找到相对应要配置的服务端 配置文件:

 

 

rdb 的启动方式

1、服务器 运行过程中重启会启动  命令: debug reload 

2、关闭服务器时候指定保存数据  命令: shutdown save 

3、主从复制时候,后面才会讲到

RDB 的缺点

存储数据量大,效率就低,

基于快照思想,IO 性能较低,

基于fork 创建子进程,内存额外消耗,

宕机可能带来的数据丢失风险

 

AOF:不写入全数据,记录部分数据,记录操作过程,对所有操作记录,排除数据丢失风险

 aof 是Redis 持久化的主流方式

AOF 功能开启:默认是不开启的。。。

配置:   appendonly yes | no   先打开配置 AOF

AOF 写数据策略 配置:   appendfsync always | everysec | no    然后根据选择使用方式持久化

  always  是有一个命令就保存一次,拉低了cpu 的性能,不推荐使用,no 是系统默认,是没办法控制的

  everysec  这种的是一秒保存一次,不管有多少命令一秒保存一次,推荐使用,就算丢失也只有一秒的数据

操作配置:

vim 打开conf 配置文件夹里的 6379 配置,然后加上AOF 的配置:

appendonly yes
appendfsync everysec

加上配置以后 :wq 保存,然后运行 6379 的端口: redis-server redis-6379.conf 

就可以发现 data 文件夹里多了一个appendonly.aof 文件

为了避免以后的aof 持久化文件过多,建议使用appendonly-xxx端口号.aof  的这种格式

AOF 重写:提高效率

手动重写:   bgrewriteaof   执行这个命令以后,会返回结果通知,后台已经开始重写了

自动重写:   auto-aof-rewrite-min-size [size] 

        auto-aof-rewrite-percentage [percentage] 

RDB 和 AOF 的区别

事务    redis 事务就是一个命令执行的队列,将一系列预定义的命令包装成一个整体,一次性按添加顺序执行,直接不被打断或干扰 

一个队列中、一次性、顺序性、不被打断干扰

 事务基本操作:

开启事务: multi   设定事务开启位置,后面的所有指令都加在了事务里

执行事务: exec   设定事务结束位置,同时执行事务,和multi 成对使用,成对出现

在multi 和 exec 中间这一段的所有命令,都在事务里,操作非常简单。。

取消事务: discard   终止当前事务,在multi 之后 和 exec 之前使用!

注意:如果在事务中输入指令错误,那么事务里将会解析命令错误,就会报错,比如:set 写成了 est ,就会报错

   如果命令的类型不匹配,也不行,比如:lpush xx 虽然不会报错,但是结束,执行事务时候就会报错。但是后面的指令还是会执行!

所以redis 的事务不支持回滚,如果真的出错了,推荐思路:百度把。。。  因为redis 的事务在企业中用的比较少

 

事务锁

用于业务场景:开始事务以后,如果在执行事务之前,被另一个客户端 或者 其他方法更改或执行了命令 事务里指定的key ,那个这个事务不会执行了,返回nil 空

watch [key1] [key2]...    只能用在开始事务multi 的前面,不能写在事务里面!就是只能在执行事务之前加 锁
unwatch    如果在watch key1 key2...  后面加上uwatch 命令,那么这个锁就取消了

分布式锁  比如三个人同时买一个东西,这个东西只有一个,那么其他两个人就买不到了

由于数值一直在改变,因为东西在一直卖出去嘛,所以watch 事务锁已经不能解决这个问题了

解决方案:  使用 setnx 设置一个公共锁,就是锁住了公共的方法后,别人都不能用了

setnx lock-key [value]:  比如:set num 10 命令以后,setnx lock-num 1,这个值无所谓,

            然后可以incrby num -1 就等于10-1了,然后再释放锁:del lock-num

死锁:比如:正在锁住的情况下,宕机了,可是锁还是锁住了,就像上厕所把门锁住了,可你却睡着了。。。。哈哈

解决方案:设置规定时间,长时间不释放锁,就把锁给砸了。。。

expire lock-key [second]    在setnx lock-key value  的下面用expire lock-key second ,比如:expire lock-num 10  十秒后锁就失效了,当然也可以提前释放锁。
pexpire lock-key [milliseconds]  这个是毫秒

一般使用毫秒执行业务比较多,不适合锁住太长时间

 

删除策略

过期数据  就是以前redis 里面定义的有效期的数据,但是过多,影响了cpu 的性能,给cpu 增加了压力,但是这些数据又不急着操作

数据删除策略:

1、定时删除

  创建一个定时器,当 key 设置的有效时间过了时候,由定时器操作,优点就是节约内存,缺点就是增加了cpu 的压力,因为到点了就删除

  总结:定时删除就是拿处理器的性能换取了内存储存空间,拿时间换空间

2、惰性删除

  和定时删除对比鲜明,数据的设置时间到期了也不删除,等到下次再调用这个数据时候,提示你数据不存在,这个时候才删除

  优缺点也很明显,节约了cpu 的性能,但是内存压力就大了

  总结:就是拿存储空间换取处理器性能,拿空间换时间

3、定期删除

  以上两种策略都太极端了,这里的定期删除时折中的方案

redis 里使用的时惰性删除 和 定期删除 这两种方案

 

逐出算法

逐出算法的8 种配置:

 

服务器配置:redis.conf    平常可能用不到,用的很少

设置服务器守护进程方式运行:  daemonize yes | no
绑定主机地址:    bind 127.0.0.1
设置服务器端口号:    port 6379
设置数据库数量:     databases 16

这些都是再conf 的各个配置文件里加上就行了

日志配置:

服务器指定日志记录级别:  loglevel debug | verbose | notice | warning    默认的是verbose 
日志记录文件名:  logfile 端口号.log

客户端配置:

设置最大连接客户端数量,默认是无限制的:    maxclients 0    达到上限,redis 就关闭新的连接了
客户端空闲等的时间:    timeout 300    300 秒后如果客户端没有任何操作,就给关了。取消该功能就设置为 0

 

高级数据类型: Bitmaps、HyperLogLog、GEO

Bitmaps  是以String 类型二进制中存储的位 进行存储,是做状态统计的

setbit [key] [二进制下标位置] [设置数值]    比如:setbit bits 0 1    或者setbit bits 100 1  二进制长度不要过长,影响性能
                        获取:getbit bits 0  返回1

 

HyperLogLog    做计数统计的

GEO  是做地理位置,心机计算的。用于坐标,计算坐标点距离,比如地图软件、附近人什么的功能这些里都用到了

            横坐标    纵坐标    名字

                          单位  

GEO 算的是水平位置,比如地图上平面的,如果是比如:山上到山下的位置,在地图上就是垂直的了,这个是不能计算距离的

测试:

 

集群  主从复制、哨兵模式、集群

主从复制

1、建立连接  

推荐使用方法三

比如在 6380端口的服务器(从表)要连 6379端口号的服务器(主表),

打开6380 的配置文件,加上配置:   slaveof 127.0.0.1 6379   

 

主 从 断开连接: slaveof no one   从 从服务器客户端 输入这个命令就断开和主机的连接了

 

2、数据同步

如果由于master 的缓冲区过小,所以导致缓冲区一直存在数据,就会一直主从复制,就造成了死循环

解决办法:在master 服务器设置一下 缓冲区的大小,多少合适呢?:

 运行id:

比如说突然断电了,或者闪连了,中间断开了一些时间,那么在重新连接时候,master 会验证 之前连接的slave 的运行id ,

从而来判断是不是刚刚连接的那台slave ,如果是,那就继续链接,如果不是,就会连接失败连接不上的。

运行id 是一个 40位的字符。

 

偏移量:主要用于部分复制

 

3、命令传播

细化全量复制 + 部分复制

 心跳机制:主要就是看主、从 服务器是不是还连接上的,有没有断开短接,就是隔一会就ping,然后那边 pong

哨兵模式

哨兵一般都是配置的奇数,多个哨兵,最少配置三个

 哨兵结构搭建:

然后保存退出

然后把这个复制三份,就是三个哨兵。

这时候可以去把主、从 服务器都启动。

然后就可以先启动一个哨兵:命令: redis-sentinel sentinel-26379.conf   

用这个命令把三个哨兵都启动,然后主、从服务器,客户端都正常使用

注意:如果其中master 挂掉了,会有一个哨兵发现这件事,其他哨兵一起来进行投票,决定真的挂掉了,然后再随机

挑选一个slave 来当master ,确保正常使用

 

集群

如果要加一个redis,把其他的储存的槽分一点到这个新的redis空间里,redis 集群之间相互都是联系着的,每个redis 都知道各个redis 之间

存储的槽的位置id,当客户访问数据时,如果第一次没有找对槽的位置,就会返回给服务器告诉具体的槽在哪个位置,最多两次就找到了

集群搭建

找到redis.conf 这个的redis 配置文件,然后如上图配置完成保存退出,然后把这个可以复制一份,改名字redis-6379.conf,

然后复制这个文件多份,做集群,最好都是redis-xxx端口号.conf 文件名

然后依次启动多个redis 的集群,可以靠各个端口号区分开的

启动redis 集群:要事先下载好有ruby 和 gem ,这两个东西版本要一样

然后执行  ./redis-trib.rb   这个命令,后面跟上所有的集群ip 地址:端口号

回车确定这个命令以后,发现信息打印出来了,告诉你每个redis 的空间的槽是多少,哪些是master 哪些是 slave 等等

然后输入 yes 确认

然后又会打印信息,哪些redis集群加入了,槽 的编号什么的,redis 集群搭建完成

存取数据

集群里面启动客户端的命令是  redis-cli -c   要加上-c 才行,然后set 指令存放一个数据,有返回结果告诉说槽的编号,redis 的端口号等

拿到数据时候,必须要指定端口才行:

主从切换

如果有一个 从服务器下线掉线了,master 会告知整个redis 集群,某个slave 下线了 

如果是 主服务器master 掉了连不上了,slave 会根据你的设置来进行等待连接,一秒连一次,直至发现连不上主服务器了,

就会有slave 自己谋朝篡位,当上了master 顶上去了,就算原来的主服务器又上来了,也不能当主服务了,只能当 从服务了 

 

缓存预热

当服务器刚起来时候,缓存里没有数据,处理器就会加速运转导致压力过大,为了避免数据访问时候直接从数据库拿数据,然后放在

缓存里给处理器增加压力。所以提前把数据放入缓存里

缓存雪崩

数据访问再瞬间突然变得很大,缓存里的数据跟不上,服务器也会崩了。

缓存击穿

和雪崩有一些相似,redis 内存平稳无波动,但是数据库崩溃。

一般问题是:原因是拿到的都是同一个key ,说明这个key 过期了

 

缓存穿透

在正常节日中,也没有抢购什么的业务,服务器突然崩了,感觉访问量比过节时候还多,

问题排查发现:redis 有大面积未命中,就是有很多key 无效了,结果发现很多非正常的URL 轮径的访问

一般的黑客攻击会想办法弄瘫痪公司的服务器,所以故意弄了很多不正确的url 访问

解决方案:还是从黑客的角度解决

 

性能指标监控

 

好了,redis 可以先告一段落啦~

期待下期吧

posted @ 2020-08-05 17:14  aBiu--  阅读(160)  评论(0编辑  收藏  举报