关于redis:游戏的-Redis-选用思考

40次阅读

共计 1272 个字符,预计需要花费 4 分钟才能阅读完成。

此处仅是收集材料的一些小结,若有舛误,还望不吝赐教。

背景:思考到游戏的高频读写行为,Demo 中将 Redis 作为一级存储,定时向 MySQL 进行二级存储。

游戏体验还不错,于是打算制作正式版,就延展出了不少对于效率和永恒缓存的遐思,这里简略赘述一二。

对于存储构造:String vs Hash

这个问题最后不存在,我是间接用 String convert to JSON,而后看到了汉家松鼠的技术总结,他们采纳的是 Hash,就此产生了 diff 这两者的想法。

简略的思考了一下,也参考了 Redis strings vs Redis hashes to represent JSON: efficiency? 等发问。

Hash 的特点:

  • K-V 式的读取,500kb 的数据里,间接读到你须要的 value,高效!
  • K 须要额定的存储空间。
  • 嵌套对象不易存储,问题不大,除非是 MongoDB 爱好者。
  • K 的可用性须要额定保障。

String 的特点:

  • 一口气寄存所有数据,会比拟大,对于 500kb 这种,能够拆分为多个局部来存储。
  • 须要额定转码——譬如 PHP 的 json_decode 还有优化空间,会有性能思考。
  • 无奈定制化的做 TTL。

TTL 由转储动作来自行处理,毕竟不是缓存,而是二级数据库,不思考过期。
转码性能也须要玩家到一定量级,而且能够配合拆分构造、重写 json decode 来优化。

只管 Hash 仿佛也不错,最终对我并没有特地重大的吸引力,仍放弃 String 来解决。

对于 Redis to MySQL

这个问题发现的比拟早,如何稳固、牢靠的让 Redis 数据定期进入 MySQL,不然玩家会丢档。v2ex 上也发问过,技术大佬们提了很多计划:

  • 工夫轮:工夫戳作为 key,玩家数据的快照作为 value,定时器每秒解决本工夫戳的所有 value,将其实例化入 MySQL;玩家信息更新时,将本身的工夫戳 +60s,存入工夫轮。
  • 有序列表:每次只需扫描表头,和工夫轮相似,更省事。
  • spacekey:Redis 官网性能,当缓存生效时能够触发一个事件,问题在于,这个事件首先默认不反对集群(但能够手动订阅),其次这个事件在客户端 shutdown 时,会失落在这期间的 message。不是很稳固。
  • MQ 延时队列 & 死信队列:将数据丢进去,延时解决。

死信队列

从未听过,就简略探索了一下。

队列的 TTL 过期解决形式是退出另一个队列——咱们将另一个队列,称之为“死信队列”(dead message queue — 字面意思),而后由死信消费者来解决。

  1. 将数据存入队列后,设置 TTL;
  2. 期待数据过期,被失常队列丢入死信队列;
  3. 死信队列的消费者逐条生产。

这里还有一个益处:

假使咱们针对每条信息设置 TTL,当失常队列的“过期信息”太多时,新的过期音讯并不会立即丢入死信队列,而是按程序、按压力来由失常队列稳固丢入死信队列。

死信消费者就无需担心压力问题,失常队列会帮忙削峰。

(感激 Rocketer 大佬,若非他点进去,我这种 MQ 萌新真的会漏掉这一点,很有意思)

# Dead Letter Exchanges
(强烈建议玩 MQ 的萌新读 RabbitMQ 的官网技术博文,很多技术问题的探讨都很有深度)

正文完
 0