Redis开发运维实践开发者设计规范之延迟考虑

4.5 延迟考虑

1. 尽可能使用批量操作:

  • mget、hmget而不是get和hget,对于set也是如此。
  • lpush向一个list一次性导入多个元素,而不用lset一个个添加
  • LRANGE 一次取出一个范围的元素,也不用LINDEX一个个取出

2. 尽可能的把redis和APP SERVER部署在一个网段甚至一台机器。

3. 对于数据量较大的集合,不要轻易进行删除操作,这样会阻塞服务器,一般采用重命名+批量删除的策略:

排序集合:

# Rename the key
newkey = "gc:hashes:" + redis.INCR("gc:index")
redis.RENAME("my.zset.key", newkey)

# Delete members from the sorted set in batche of 100s
while redis.ZCARD(newkey) > 0
 redis.ZREMRANGEBYRANK(newkey, 0, 99)
end

集合:

# Rename the key
newkey = "gc:hashes:" + redis.INCR("gc:index")
redis.RENAME("my.set.key", newkey)

# Delete members from the set in batches of 100
cursor = 0
loop
 cursor, members = redis.SSCAN(newkey, cursor, "COUNT", 100)
 if size of members > 0
redis.SREM(newkey, members)
 end
 if cursor == 0
break
 end
end

列表:

# Rename the key
newkey = "gc:hashes:" + redis.INCR("gc:index")
redis.RENAME("my.list.key", newkey)

# Trim off elements in batche of 100s
while redis.LLEN(newkey) > 0
 redis.LTRIM(newkey, 0, -99)
end

Hash:

# Rename the key
newkey = "gc:hashes:" + redis.INCR( "gc:index" )
redis.RENAME("my.hash.key", newkey)

# Delete fields from the hash in batche of 100s
cursor = 0
loop
 cursor, hash_keys = redis.HSCAN(newkey, cursor, "COUNT", 100)
 if hash_keys count > 0
redis.HDEL(newkey, hash_keys)
 end
 if cursor == 0
break
 end
end

4. 尽可能使用不要超过1M大小的kv。

5. 减少对大数据集的高时间复杂度的操作:根据复杂度计算,如下命令可以优化:


6. 尽可能使用pipeline操作:一次性的发送命令比一个个发要减少网络延迟和单个处理开销。一个性能测试结果为(注意并不是pipeline越大效率越高,注意最后一个测试结果) :

logger@BIGD1TMP:~> redis-benchmark -q -r 100000 -n 1000000 -c 50
PING_INLINE: 90155.07 requests per second
PING_BULK: 92302.02 requests per second
SET: 85070.18 requests per second
GET: 86184.61 requests per second

logger@BIGD1TMP:~> redis-benchmark -q -r 100000 -n 1000000 -c 50 -P 10
PING_INLINE: 558035.69 requests per second
PING_BULK: 668002.69 requests per second
SET: 275027.50 requests per second
GET: 376647.84 requests per second

logger@BIGD1TMP:~> redis-benchmark -q -r 100000 -n 1000000 -c 50 -P 20
PING_INLINE: 705716.25 requests per second
PING_BULK: 869565.25 requests per second
SET: 343406.59 requests per second
GET: 459347.72 requests per second

logger@BIGD1TMP:~> redis-benchmark -q -r 100000 -n 1000000 -c 50 -P 50
PING_INLINE: 940733.81 requests per second
PING_BULK: 1317523.00 requests per second
SET: 380807.31 requests per second
GET: 523834.47 requests per second

logger@BIGD1TMP:~> redis-benchmark -q -r 100000 -n 1000000 -c 50 -P 100
PING_INLINE: 999000.94 requests per second
PING_BULK: 1440922.12 requests per second
SET: 386996.88 requests per second
GET: 602046.94 requests per second

logger@BIGD1TMP:~> redis-benchmark -q -r 100000 -n 1000000 -c 50 -P 200
PING_INLINE: 1078748.62 requests per second
PING_BULK: 1381215.50 requests per second
SET: 379218.81 requests per second
GET: 537634.38 requests per second

一个场景是一个购物车的设计,一般的设计思路是:

在获取购物车内部货品时,不使用pipeline会很低效: 可以修改为:

7. 如果出现频繁对string进行append操作,则请使用list进行push操作,取出时使用pop。这样避免string频繁分配内存导致的延时。

8. 如果要sort的集合非常大的话排序就会消耗很长时间。由于redis单线程的,所以长时间的排序操作会阻塞其他client的 请求。解决办法是通过主从复制机制将数据复制到多个slave上。然后我们只在slave上做排序操作。把可能的对排序结果缓存。另外就是一个方案是就是采用sorted set对需要按某个顺序访问的集合建立索引。

Redis开发运维实践指南

本文为《Redis开发运维实践指南》内容,该书作者为黄鹏程,已授权转载。

时间: 2024-08-01 01:20:53

Redis开发运维实践开发者设计规范之延迟考虑的相关文章

Redis开发运维实践开发者设计规范之典型使用场景参考

4.6 典型使用场景参考 下面是Redis适用的一些场景: 1. 取最新 N 个数据的操作 比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的 5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取. 使用LPUSH latest.comments命令,向 list集合中插入数据 插入完成后再用 LTRIM latest.comments 0 5000 命令使其永远只保存最近5000个 ID 然后我们在客户端获取某一页评论时可以用下面的逻辑 FUNCTION

Redis开发运维实践开发者设计规范之客户端推荐

4.7 客户端推荐 4.7.1 Redis-Python驱动的安装和使用 unzip redis-py-master.zip cd redis-py-master/ sudo python setup.py install 完成后import redis即可. 4.7.2 Redis-Java客户端推荐 Jedis :https://github.com/xetorthio/jedis 重点推荐 Spring Data redis :https://github.com/spring-proje

Redis开发运维实践开发设计规范之key设计

4.1 Key设计 key的一个格式约定:object-type:id:field.用":"分隔域,用"."作为单词间的连接,如"comment:12345:reply.to".不推荐含义不清的key和特别长的key. 一般的设计方法如下: 1: 把表名转换为key前缀 如, tag: 2: 第2段放置用于区分区key的字段--对应mysql中的主键的列名,如userid 3: 第3段放置主键值,如2,3,4...., a , b ,c 4: 第

Redis开发运维实践开发设计规范之数据异常处理

4.3 数据异常处理 程序应该处理如果redis数据丢失时的清理redis内存和重新加载的过程. Redis开发运维实践指南

Redis开发运维实践开发设计规范之内存考虑

4.4 内存考虑 只要有可能的话,就尽量使用散列键而不是字符串键来储存键值对数据,因为散列键管理方便.能够避免键名冲突.并且还能够节约内存. 具体实例: 节约内存:Instagram的Redis实践 blog.nosqlfan.com/html/3379.html 如果将redis作为cache进行频繁读写和超时删除等,此时应该避免设置较大的k-v,因为这样会导致redis的 内存碎片增加,导致rss占用较大,最后被操作系统OOM killer干掉.一个很具体的issue例子请见:https:/

Redis开发运维实践开发设计规范之超时设置

4.2 超时设置 从业务需求逻辑和内存的角度,尽可能的设置key存活时间. Redis开发运维实践指南

Redis开发运维实践问题处理只延迟检查

6.2.1 检查CPU情况 mpstat -P ALL 1 6.2.2 检查网络情况 可以在系统不繁忙或者临时下线前检测客户端和server或者proxy 的带宽: 1)使用 iperf -s 命令将 Iperf 启动为 server 模式: iperf –s -------------------- Server listening on TCP port 5001 TCP window size: 8.00 KByte (default) -------------------- 2)启动客

Redis开发运维实践数据操作之集合操作

2.4.1 添加元素 sadd key member 成功返回1,如果元素以及在集合中返回0,key对应的set不存在返回错误 2.4.2 移除元素 srem key member 成功返回1,如果member在集合中不存在或者key不存在返回0,如果key对应的不是set类型的值返回错误 2.4.3 删除并返回元素 spop key 如果set是空或者key不存在返回nil 2.4.4 随机返回一个元素 srandmember key 同spop,随机取set中的一个元素,但是不删除元素 2.

Redis开发运维实践上线部署规划之内存规划

5.1 内存.CPU规划 一定要设置最大内存maxmemory参数,否则物理内存用爆了就会大量使用Swap,写RDB文件时的速度很慢.注意这个参数指的是info中的used_memory,在一些不利于jmalloc的时候,内存碎片会很大. 多留55%内存是最安全的.重写AOF文件和RDB文件的进程(即使不做持久化,复制到Slave的时候也要写RDB)会fork出一条新进程来,采用了操作系统的Copy-On-Write策略(子进程与父进程共享Page.如果父进程的Page-每页4K有修改,父进程自