- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详解Redis瘦身指南由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
redis 服务器的最大占用内存量由配置项 maxmemory 决定,我们可以通过 config set maxmemory 2gb 的格式来配置。一旦 redis 内存满,所有引起内存增加的操作都会被返回 error。作为专业 redis 服务器我们通常将此项设置为0,以服务器系统内存来作为限制; 。
那么 redis 使用内存达到了上限怎么办?redis 为我们提供了几种选项以自动回收内存,可以通过配置项 maxmemory-policy 来配置; 。
最大内存回收策略需要根据业务来配置,如果纯粹做缓存,allkeys-lru无疑是最合适的。如果存储了稍微重要的数据,为了防止 redis 误删一些重要键,则需要选用 noeviction; 。
allkeys-lru、allkeys-random 在内存满时都有键可删,可以腾出内存,但如果配置了其他的策略,数据库用久了(根据业务量),随着业务发展和数据积累,通常会累积到到服务器内存占用率高,利用率低的情况,则可能会遇到内存占用满的问题.
产生问题的原因有:
持久键废弃 。
这是导致此问题的最常见情况.
有时候是开发人员的锅,开发不规范,未给有时效性的键设置过期时间,后续又不进行手动删除,键就成为无人管的孤儿键了.
还可能是整个业务慢慢被废弃,不知道哪一天起,业务整体已不再维护了,一批键自然也就没用了。比这更严重的是,如果使用 list 传递数据,消费进程已被停止,但生产进程未同步停止,还在往 redis 里写数据.
过期键未回收 。
这个原因首先要谈到 redis 的两种过期键删除策略:
如果我们产生过期键的速度很快,最多可导致 redis 25% 的过期键没有被及时删除.
由上,明白了问题产生的原因,解决 redis 内存满的方法就明确了:清除这些垃圾键。 于是就面临着两个问题:
如何遍历键 。
对于查找键,我们首先想到的是 keys,但 keys 的时间复杂度是o(n),n 是 redis 内键的总数,如果 redis 内键很多还是会有性能问题,导致其他命令被阻塞的.
这里介绍一个键遍历命令: scan.
1
2
3
4
|
scan cursor:
0 => cursor, // cursor = 0 遍历结束
1 => array(key1, key2...)
|
需要注意的是 scan 命令是在版本2.8.0 加入的,如果是之前的版本,可以考虑解析 redis 的 rdb 文件来获取所有的键.
如何判断键是否垃圾 。
我们有三种异常键需要处理:
这里介绍 redis 的另一个命令 object,使用它可以从内部查看 key 对象的状态。使用 object idletime key 来获取 key 的闲置时间,我们可以判断 key 闲置时间大于一个时间段(根据业务自定)的为已废弃.
此外还能使用 object refcount key获取 key 引用所储存的值的次数,object encoding key 获取 key 储存的值所使用的内部表示.
获取键大小 。
而获取 redis 某键占用内存大小,则通过另一个命令 debug object 来获取,此命令会返回比object命令更详细的内部数据.
1
2
|
debug object test
value at:0x7fb0ee16ebd0 refcount:1 encoding:embstr serializedlength:6 lru:12362780 lru_seconds_idle:4
|
结果包括内存地址、引用数、内部编码表示、序列化后的长度、最近最少使用标识值,闲置时间,我们可以解析此结果串来获取对应的数据.
需要注意,key 作为复合键拥有大量字段时使用 debug 命令计算内存会使 redis 阻塞较长时间,且 redis 官方并不建议在客户端使用此命令.
我们也可以先使用 type key 获取键的类型,再根据类型获取其键的大小,如对字符串使用len,对 哈希表使用hlen.
要注意在删除特别大的复合键时,建议先逐步清空键内的字段,防止因字段过多,redis 阻塞较长时间.
管道加速 。
redis 支持 pipeline 管道技术,一次 请求/响应 服务器能实现处理并响应多个请求。这样就可以将多个命令同时发送到服务器,不等待回复,直接在最后获取多个结果.
php 中使用 multi(redis::pipeline) 和 exec() 命令来实现管道; 。
脚本实现 。
下面是个简单的脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$redis = new redis();
$redis->connect('127.0.0.1');
do {
$keys = $redis->scan($cursor);
$pipeline = $redis->multi(redis::pipeline);
foreach ($keys as $key) {
$idle_time = $redis->object('idletime', $key);
if ($idle_time > 180 * 24 * 3600) {
$pipeline->del($key);
}
// todo 判断类型进而判断占用内存大小,再删除
}
$pipeline->exec();
} while ($cursor != 0);
|
以上的脚本肯定也会在删除键时影响 redis 的效率,最好的情况还是从根源就避免此类情况,以下是一些建议:
redis假死 。
我在使用守护进程时 redis 有假死情况,php 和 redis 都不报错,但命令都返回 false,这种情况可以使用 redis 的 ping() 命令,来探测 redis 连接是否还在,如果不在则再建立新的连接。此问题很可能是由服务器配置引起的,如果您有知道此问题的原由或有好的解决办法,烦请指点一二.
危险命令 。
不要在没看文档的情况下在线上使用 redis 命令,例如 debug segfault,别问我怎么知道的.
以上就是详解redis瘦身指南的详细内容,更多关于redis瘦身指南的资料请关注我其它相关文章! 。
最后此篇关于详解Redis瘦身指南的文章就讲到这里了,如果你想了解更多关于详解Redis瘦身指南的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一个关于 Redis Pubsub 的练习,如下所示: 如果发布者发布消息但订阅者没有收到服务器崩溃。订阅者如何在重启服务器时收到该消息? 请帮帮我,谢谢! 最佳答案 在这种情况下,消息将永远消失
我们正在使用 Service Stack 的 RedisClient 的 BlockingDequeue 来保存一些数据,直到它可以被处理。调用代码看起来像 using (var client =
我有一个 Redis 服务器和多个 Redis 客户端。每个 Redis 客户端都是一个 WebSocket+HTTP 服务器,其中包括管理 WebSocket 连接。这些 WebSocket+HTT
我有多个 Redis 实例。我使用不同的端口创建了一个集群。现在我想将数据从预先存在的 redis 实例传输到集群。我知道如何将数据从一个实例传输到集群,但是当实例多于一个时,我无法做到这一点。 最佳
配置:三个redis集群分区,跨三组一主一从。当 Master 宕机时,Lettuce 会立即检测到中断并开始重试。但是,Lettuce 没有检测到关联的 slave 已经将自己提升为 master
我想根据从指定集合中检索这些键来删除 Redis 键(及其数据集),例如: HMSET id:1 password 123 category milk HMSET id:2 password 456
我正在编写一个机器人(其中包含要禁用的命令列表),用于监视 Redis。它通过执行禁用命令,例如 (rename-command ZADD "")当我重新启动我的机器人时,如果要禁用的命令列表发生变化
我的任务是为大量听众使用发布/订阅。这是来自 docs 的订阅的简化示例: r = redis.StrictRedis(...) p = r.pubsub() p.subscribe('my-firs
我一直在阅读有关使用 Redis 哨兵进行故障转移的内容。我打算有1个master+1个slave,如果master宕机超过1分钟,就把slave变成master。我知道这在 Sentinel 中是
与仅使用常规 Redis 和创建分片相比,使用 Redis 集群有哪些优势? 在我看来,Redis Cluster 更注重数据安全(让主从架构解决故障)。 最佳答案 我认为当您需要在不丢失任何数据的情
由于 Redis 以被动和主动方式使 key 过期, 有没有办法得到一个 key ,即使它的过期时间已过 (但 在 Redis 中仍然存在 )? 最佳答案 DEBUG OBJECT myKey 将返回
我想用redis lua来实现monitor命令,而不是redis-cli monitor。但我不知道怎么办。 redis.call('monitor') 不起作用。 最佳答案 您不能从 Redis
我读过 https://github.com/redisson/redisson 我发现有几个 Redis 复制设置(包括对 AWS ElastiCache 和 Azure Redis 缓存的支持)
Microsoft.AspNet.SignalR.Redis 和 StackExchange.Redis.Extensions.Core 在同一个项目中使用。前者需要StackExchange.Red
1. 认识 Redis Redis(Remote Dictionary Server)远程词典服务器,是一个基于内存的键值对型 NoSQL 数据库。 特征: 键值(key-value)型,value
1. Redis 数据结构介绍 Redis 是一个 key-value 的数据库,key 一般是 String 类型,但 value 类型多种多样,下面就举了几个例子: value 类型 示例 Str
1. 什么是缓存 缓存(Cache) 就是数据交换的缓冲区,是存贮数据的临时地方,一般读写性能较高。 缓存的作用: 降低后端负载 提高读写效率,降低响应时间 缓存的成本: 数据一致性成本 代码维护成本
我有一份记录 list 。对于我的每条记录,我都需要进行一些繁重的计算,因为我要在Redis中创建反向索引。为了达到到达记录,需要在管道中执行多个redis命令(sadd为100 s + set为1
我有一个三节点Redis和3节点哨兵,一切正常,所有主服务器和从属服务器都经过验证,并且哨兵配置文件已与所有Redis和哨兵节点一起更新,但是问题是当Redis主服务器关闭并且哨兵希望选举失败者时再次
我正在尝试计算Redis中存储的消息之间的响应时间。但是我不知道该怎么做。 首先,我必须像这样存储chat_messages的时间流 ZADD conversation:CONVERSATION_ID
我是一名优秀的程序员,十分优秀!