zl程序教程

您现在的位置是:首页 >  后端

当前栏目

20180705-关于army队列的解决方法

方法队列队列 解决 关于
2023-09-27 14:25:55 时间

前天提到了对于army队列的需求,简约一下,对于队列,并不需要时刻将变化都持久化存储下来,因为这些都是内存中计算的数据,需要常驻内存,而需要做的,是在服务器关机或者宕机的时候,将内存中的army队列加载到某种持久化存储,在服务器启动时,再从此持久化存储部分加载到内存中。

对于持久化存储部分,我之前考虑过redis和mongo,memcached的内存管理不适合存储这样的value值,memcache适用的场景是小容量的缓存机制。接下来redis也被排除,虽然redis的string类型的值最大是500M足可以满足需求但在将内存中的army队列存储进redis时,redis的内存占用会快速激增,在超出配置中的最大内存时,会导致根据配置策略对k进行清理。即使在不超出最大配置的内存,但却逼近物理机的内存上限时,redis将会进行持久化存储用于压缩内存,有aof和rof两种方式,这两种方式都是使用copy-on-write的方式开辟新的进程进行处理,但是注意下这个时刻,redis使用了系统的磁盘缓存,而不是像mysql那样自己创建磁盘缓存自己来管理,当逼近内存上限时,会引发磁盘缓存的不足,从而引发内存和磁盘的数据交换来保证内存的可用,这会导致系统抖动。

至于排除mysql的原因,是因为这个数据库是基于严格的关系型和强事物的,每一次对数据的操作都会将是否成功返回给调用方。相比mongo,这是有性能损失的,mongo使用了内存换时间的通用做法,先将数据写入内存,然后在某一时候写入磁盘。

这里有篇文章对mongo和mysql进行了对比 https://blog.csdn.net/clh604/article/details/19608869

在这里就不贴出详细的数据了,其实是应该亲自做出数据记录和对比的,但是我想把精力和注意力都放在系统集成上,接下来需要先写出针对mongo单独的测试用例,除此之外,对于之前业务中的侵入性的mongo代码还需要予以去除,并对宕机和重启时刻的内存可用性做出测试。

在当初我是打算就将整个army队列作为一个元祖文档写入Mongo的,类似于redis的aof方式,但是后来查询下,mongo单个文档记录只有16M,就只好将army队列一个一个插入,这种在存储层强制的规约也是逼迫开发人员详细的设计自己的数据结构。