libshmcache阅读笔记
github地址:https://github.com/happyfish100/libshmcache
libshmcache是在共享内存上实现了一个key/value的cache,据说性能比redis高很多。不过redis是带持久化的,libshmcache作为cache是不带持久化的。
libshmcache跟memcache更相似,不过memcache通信是通过socket的,而libshmcache是直接操作共享内存,会减少拷贝次数。
看了libshmcache源码,大概的数据结构是:
对于key:维护一个FIFO的ring buffer,即先来先插入,当需要回收的时候,将前面的先回收了。对key还维护了一个hash_table,将key进行hash之后插入指定节点。
对于value:libshmcache维护了多块内存,这里称为striping,把一个key/value称为entry,实际上key和value是分开存储的,所以entry理解为key更合适。同时维护两个队列,记录doing队列里的striping是可用态,done为不可用。。
对于striping:整个value存储空间是一块大内存,然后划分成多块连续的striping。当有新entry插入时,striping再分配一部分内存出来。
striping维护一个begin,代表在hash_table这个大数组中的偏移。end代表结尾的偏移。offset代表当前的偏移。
分配新内存时只移动offset,如果end-offset < size则说明不够分配。
如果offset移动到end,或者分配失败次数到达一定次数,则将striping标记为done状态,并丢进done队列里。
回收机制:在内存不够的时候,可以选择回收指定数量的value,或者回收到有一个striping为空为止。回收通过key的FIFO ring buffer回收。
淘汰策略:为什么用FIFO而不用命中率更高的LRU。github上作者是说FIFO更简单,我认为还有一个原因。LRU在读的时候需要将key放到列表尾,要进行写操作,那么就需要加锁,性能会有很大影响。而FIFO读是不需要加锁的。