redis 快照和追加的区别

检查输入缓冲区内存消耗,能看到客户端输入缓冲区消耗总量为 2.4G左右,远远超过maxmemory参数设置。

RDB的问题

清除redis缓存命令 redis清除缓存机制清除redis缓存命令 redis清除缓存机制


清除redis缓存命令 redis清除缓存机制


这两种方法都可以调用,区别是call()方法是遇到就停止执行后面的内容并直接返回错误,而pcall遇到异常会忽略掉继续执行

1:fork

一个进程时,内存的数据也被了,即内存会是原来的两倍

2:每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步数据。

如果数据量大的话,而且写作比较多,必然会引起大量的磁盘io作,可能会影响性能。

3:由于快照方式是在一定间隔时间的,所以如果redis意外down掉的话,就会丢失一次快照后的所有修改。

触发快照的情况

1:根据配置规则进行自动快照

2:用户执行se或bgse命令

3:执行flushall命令

4:执行replication时

se命令执行

Se命令时,Redis会阻塞所有客户端的请求,然后同步进行快照作。

执行bgse命令时,Redis会在后台异步进行快照作,快照同时还可以响应客户端请求。可以通过lastse命令获取一次成功执行快照的时间。

flushall命令

这个命令会导致redis清除内存中的所有数据,如果定义了自动快照的条件,那么无论是否满足条件,都会进行一次快照作;如果没有定义自动快照的条件,那么就不执 行快照

AOF的问题

默认的AOF持久化策略是每秒钟fsync一次,fsync是指把缓存中的写指令记录到磁盘中,

在这种情况下,redis扔可以保持很高的性能

当然由于OS会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。

这样aof方式的持久化也还是有可能会丢失部分修改。不过可以通过配置文件告诉redis,想要通过fsync函数强制os写入磁盘的时机

AOF方式在同等数据规模的情况下,AOF文件要比RDB文件的体积大,因此AOF方式的恢复速度也要慢于RDB方式

AOF日志恢复

如果在追加日志时,恰好遇到磁盘空间满或断电等情况,导致日志写入不完整,也没有关系,

redis提供了redis-check-aof工具,可以用来进行日志修复,基本步骤如下:

1、备份被写坏的AOF文件

2、运行redis-check-aof -fix进行修复

3、用diff -u来看下两个文件的异,确认问题点

4、重启redis,加载修复后的AOF文件

AOF重写

AOF采用文件追加方式,这样会导致AOF文件越来越大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所

设定的阈(yu)值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。可以使用命令bgrewriteaof.

如何对redis做测试

'dbname'=>,

Redis 性能测试是通过同时执行多个命令实现的。

'shipping_id'=>'13',

Redis 性能测试的基本命令如下:

$ redis-benchmark [option] [option value]

例子:

redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 100000 -q

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

redis单点还是集群?可以通过工具或者命令在redis写数据,结合实际业务场景,调整写入数据内容的大小

如何连接redis

本人也是刚开始使用redis,目前接触到的根据业务的不同连接redis的情况有两种:

1、先进到redis安装目录的bin目录下,本人的机器安装在这里,即/data/redis/bin

2、在/data/redis/bin目录下可以发现有一个redis-cli文件,执行该文件后即可进入命令为:./redis-cli,由于有如果Lua脚本比较耗时,甚至Lua脚本存在问题,那么此时Lua脚本的执行会阻塞redis,直到脚本执行完毕或者外部干预将其结束密码,要输入密码,命令为:auth 密码,出现ok的时候即已经进入了redis

1、一般测试在使用redis的时候,使用的命令也较少,在此列举常用的几个:

查看所有的key:keys

查看key的value:get 某个key

(四)设置单独账户删除某个key: del 某个key

redis使用lua

如果发了雪崩,我们可以有服务降级、熔断、限流手段来拒绝一些请求,保证服务的正常。但是,这些对用户体验是有一定影响的。

redis中执行lua可以通过两种方式:

种是将lua脚本或命令直接使用redis执行,第二种相当于把脚本或命令保存到redis中,然后使用一串sha码调用(可以理解为调用函数)

例子(哨兵之间采用的协议是 gossip,是一种去中心化的协议,达成的是最终一致性。在redis中执行):

输出:

这里传入的key个数为1,所以redis是key而world是参数

这个作相当于把脚本加载到redis,得到一个SHA1的校验和,然后使用这个SHA1码来调用对于的Lua脚本,避免每次去发送Lua脚本。

例子:

执行evalsha

如:

redis提供了几个命令来管理脚本

用于将Lua脚本加载到redis内存中

用于判断sha1值是否已经加载到redis内存中

返回个数

用于清除redis内存已经加载的所有脚本

用于杀掉正在执行的Lua脚本

有一点需要注意,如果Lua脚本正在执行写作, script kill 命令不会生效,这时只能等待脚本执行结束,或使用 shutdown se 停掉redis服务

可参看 redis文档

有两种方式可以调用

其他命令可参看文档这里不赘述

一个使用Lua脚本执行redis scan命令进行批量删除的例子,文件名为 del-batch.lua

调用

执行了之后会删除符合规则 TEST_KEY 的key

redis常见问题

:哈希槽最终所在id

1. 缓存击穿

调用结果

缓存击穿是指一个请求要访问的数据,缓存中没有,但数据库中有的情况。这种情况一般都是缓存过期了。

但是这时由于并发访问这个缓存的用户特别多,这是一个热点 key,这么多用户的请求同时过来,在缓存里面没有取到数据,所以又同时去访问数据库取数据,引起数据库流量激增,压力瞬间增大,直接崩溃给你看。

所以一个数据有缓存,每次请求都从缓存中快速的返回了数据,但是某个时间点缓存失效了,某个请求在缓存中没有请求到数据,这时候我们就说这个请求就"击穿"了缓存。

针对这个场景,对应的解决方案一般来说有三种。

借助Redis setNX命令设置一个标志位就行。设置成功的放行,设置失败的就轮询等待。就是在更新缓存时加把锁

后台开一个定时任务,专门主动更新过期数据

比如程序中设置 why 这个热点 key 的时候,同时设置了过期时间为 10 分钟,那后台程序在第 8 分钟的时候,会去数据库查询数据并重新放到缓存中,同时再次设置缓存为 10 分钟。

其实上面的后台续命思想的最终体现是也是过期。

只是后台续命的思想,会主动更新缓存,适用于缓存会变的场景。会出现缓存不一致的情况,取决于你的业务场景能接受多长时间的缓存不一致。

2. 缓存穿透

缓存穿透是指一个请求要访问的数据,缓存和数据库中都没有,而用户短时间、高密度的发起这样的请求,每次都打到数据库服务上,给数据库造成了压力。一般来说这样的请求属于恶意请求。

解决方案有两种:

就是在数据库即使没有查询到数据,我们也把这次请求当做 key 缓存起来,value 可以是 NULL。下次同样请求就会命中这个 NULL,缓存层就处理了这个请求,不会对数据库产生压力。这样实现起来简单,开发成本很低。

3. 缓存雪崩

缓存雪崩是指缓存中大多数的数据在同一时间到达过期时间,而查询数据量巨大,这时候,又是缓存中没有,数据库中有的情况了。

防止雪崩的方案简单来说就是错峰过期。

在设置 key 过期时间的时候,在加上一个短的随机过期时间,这样就能避免大量缓存在同一时间过期,引起的缓存雪崩。

4. Redis 高可用架构

Redis 高可用架构,大家基本上都能想到主从、哨兵、集群这三种模式。

哨兵模式:

它主要执行三种类型的任务:

哨兵其实也是一个分布式系统,我们可以运行多个哨兵。

然后这些哨兵之间需要相互通气,交流信息,通过投票来决定是否执行自动故障迁移,以及选择哪个从作为新的主。

选举规则:

Redis 内存故障诊断及常用运维命令

redis默认没有开启密码认证,打开/etc/redis/redis.conf配置文件, (requirepass 密码)可设置认证密码,保存redis.conf,重启redis(/etc/init.d/redis-server restart)之后,需要执行(auth 密码)。示例如下:

你是否有过这种困扰:我的数据量非常小,但还是报OOM错误?

首先我给大家解释下,Redis的OOM分两种

使用redis-benchmark持续灌入数据

制造输入缓冲区压力(防止干扰,先清空数据再压测)

压测几秒钟后,触发OOM

可通过运行上述检查命令,定位到各客户端输入缓冲区的内存消耗(由大到小排序)。

一般如果定位到有连接异常,可以使用如下命令杀掉

为测试方便,我直接把积压缓冲区配置为800M。

开启redis-benchmark压测进程

检查积压缓冲区内存消耗,可以看到因为缓冲区设置过大,数据量才存储190多M,Redis就include "MMysql.class.php";无法写入了。

若客户端输出缓冲区太大如何排查?一般该场景比较少见,常见于用到了redis的 monitor 命令

上文排查过程有些Redis运维命令我认为比较实用,整理如下

脚本执行效果:

redis删除缓存,代码逻辑没问题,没有删掉

if(!$product){

redis删除缓在手动进行数据迁移时,需要执行以下步骤:存,代码逻辑没问题,没有删掉是内存分配器的分配策略。键值对的大小不一样和删改作:Redis频繁做更新作、大量过期数据删除,释放的空间(不够连续)无法得到复用,导致碎片率上升。

redis数据缓存在哪里

'member_id'=>'636389',

一、redis的数据缓存在哪里?

首先要明白redis是一个数据库,redis是一个内存数据库, 所有数据基本上都存在于内存当中, 会定时以追加或者快照的方式刷新到硬盘中. 由于redis是一个内存数据库, 所以读取写入的速度是非常快的, 所以经常被用来做数据, 页面等的缓存。

Redis常用数据类型

Redis最为常用的数据类型主要有以下几种:

StringHashListSetSorted setpub/subTransactionsRedis实际应用场景

Redis在很多方面与其他数据库解决方案不同:它使用内存提供主存储支持,而仅使用硬盘做持久性的存储;它的数据模型非常独特,用的是单线程。另一个大区别在于,你可以在开发环境中使用Redis的功能,但却不需要转到Redis。

转向Redis当然也是可取的,许多开发者从一开始就把Redis作为数据库;但设想如果你的开发环境已经搭建好,应用已经在上面运行了,那么更换数据库框架显然不那么容易。另外在一些需要大容量数据集的应用,Redis也并不适合,因为它的数据集不会超过系统可用的内存。所以如果你有大数据应用,而且主要是读取访问模式,那么Redis并不是正确的选择。

然而我喜欢Redis的一点就是你可以把它融入到你的系统中来,这就能够解决很多问题,比如那些你现有的数据库处理起来感到缓慢的任务。这些你就可以通过Redis来进行优化,或者为应用创建些新的功能。在本文中,我就想探讨一些怎样将Redis加入到现有的环境中,并利用它的原语命令等功能来解决 传统环境中碰到的一些常见问题。在这些例子中,Redis都不是作为数据库。

更多Redis相关知识,请:哈希槽访问Redis使用教程栏目!

redis ssh 入侵后怎么处理

'shipname'=>$addr['name'],

漏洞修复加固措施

(一)网络加固

绑定127.0.0.1,redis默认是的127.0.0.1上,如果仅仅是本地通信,请确保在本地。这种方式缓解了redis的风险。在redis.conf中配置如下:

bind 127.0.0.1

(二)设置防火墙

如果需要其他机器访问,或者设置了sle模式,需添加相应的防火墙设置。命令如下:

`iptables -A INPUT -s x.x.x.x -p tcp --dport 6379 -j ACCEPT`

(三)添加认证

`root@kali:~# redis-'pay_status'=>'0',cli -h 192.168.10.212

redis 192.168.10.212:6379> keys

(error) ERR operation not permitted

redis 192.168.10.212:6379> auth @nsF0cus!@#

OK`

设置一个单独的redis账户:创建一个redis账户,通过该账户启动。示例如下:

`setsidsudo -edis /usr/bin/redis-server /etc/redis/redis.conf'`

(五)重命名重要命令

由于redis没有做基本的权限分离,无管理账号和普通账号之分,导致攻击者登录后可执行任意作,因此需要隐藏重要命令,例如:FLUSHDB, FLUSHALL, KEYS, PEXPIRE, DEL, CONFIG, SHUTDOWN, BGREWRITEAOF, BGSAVE, SAVE, SPOP, SREM, RENAME, DEBUG, EVAL`。

其中在redis2.8.1和RedisRedis3.x (< 3.0.2)存在有eval沙箱逃逸漏洞,攻击者利用漏洞可执行任意lua代码。设置方法如下,还编辑redis.conf文件:

`rename-command CONFIG ""

rename-command flushall ""

rename-command flushdb ""

rename-command shutdown shutdown_wa`

上述配置将config,flushdb,flushall设置为了空,即禁用该命令,我们也可以命名为一些攻击者难以猜测,我们自己却容易记住的的名字。保存之后,执行/etc/init.d/redis-server restart 重启生效。

【Redis】Redis Cluster-集群数据迁移

一:

Redis通过对KEY计算hash,将KEY映射到slot,集群中每个负责一部分slot的方式管理数据,slot个数为16384。

在集群对应的结构体变量clusterNode中可以看到slots数组,数组的大小为CLUSTER_SLOTS除以8,CLUSTER_SLOTS的值是16384:

clusterState

clusterNode里面保存了相关的信息,集群数据迁移信息并未保存在clusterNode中,而是使用了clusterState结构体来保存:

clusterState与clusterNode的关系

在进行数据迁移之前,首先在需要迁入的目标使用 SETSLOT 命令标记要将SLOT从哪个迁入到当前:

然后在源也就是slot所在使用 MIGRATING 命令标记将数据迁出到哪个:

比如slot1当前在node1中,需要将slot1迁出到node2,那么首先在nodd2上执行 IMPORTING 命令,标记slot准备从node1迁到当前node2中:

然后在node1中执行 MIGRATING 命令标记slotCLUSTER SETSLOT NODE 命令的处理依旧在 clusterCommand 函数中,处理逻辑如下:1需要迁移到node2:

clusterCommand

SETSLOT 命令的处理在clusterCommand函数(cluster.c文件中)中:

在标记完迁入、迁出后,就可以使用 CLUSTER GETKEYSINSLOT 命令获取待迁出的KEY:

:哈希槽的值

:迁出KEY的数量

getkeysinslot 命令的处理也在clusterCommand函数中,处理逻辑如下:

完成上两步之后,接下来需要在源中执行 MIGRATE 命令进行数据迁移, MIGRATE 既支持单个KEY的迁移,也支持多个KEY的迁移,语法如下:

migrateCommand

MIGRATE 命令对应的处理函数在migrateCommand中(cluster.c文件中),处理逻辑如下:

createDumpPayload

createDumpPayload函数在cluster.c文件中:

restoreCommand

目标收到迁移的数据的处理逻辑在restoreCommand中(cluster.c文件中):

数据迁移的一步, 需要使用 CLUSTER SETSLOT 命令,在源和目标执行以下命令,标记slot最终所属的,并清除步中标记的迁移信息 :

clusterCommand

总结

参考

极客时间 - Redis源码剖析与实战(蒋德钧)

Redis版本:redis-6.2.5