Memcached哈希性能优化(八)——总结报告
Memcached哈希性能优化报告
一、 Memcached分析
1. 内存管理
- 和一般的内存管理差不过, memcached从操作系统获取到一大块内存后, 便把这大块内存划分为各种大小的chunk块, chunk块大小按照比例逐渐递增,这个可以由用户来指定完成。
- 每个slabclass含有多个slab,一个slab是一个大小为1M的内存块,这个slab块的会被按照chunk块的大小进行分割进行分配。
- 从 slab管理器分配item的时候, 首先计算item的大小, 找到大小刚好大于等于某个chunk块size所在的slabclass,然后进行分配。
- 分配的逻辑很简单,如果有空闲的或是回收回来item的话,则直接分配从这个chunk块,否则尝试申请新的slab的然后进行分配,再要没有就只能返回NULL让LRU去替换了。
- 存在内存碎片, 比如说, 将48字节的item存储到一个64字节的 chunk, 就有16字节的内存浪费。
- 另外,由于slab是唯一的,必须采用slab_lock保证分配的原子性,也就是说如果多线程分配的话,如果cache_lock间冲突假设没有的话,到这个slab去申请内存的话也只能是单一的申请,所以决定了插入的过程的最终瓶颈就是这里了,而这里对内存的管理如果把他也分块的话导致后续的逻辑比较难处理,所以这个其实没有处理。
2. hash和LRU
![](/assets/blank.gif)
- 链式hash的实现很经典,但是由于是链表保存,数据的局部性很不好,所以内存的访问效率就会有所下降。
- LRU的那个双向链表的实现,插入和读取都要调整item在LRU表中的位置,这2个操作明显需要上锁,其实读取本身不需要上锁的,但是要调整LRU的位置,所以没有办法在do_item_link和do_item_unlink中我们都能发现要上锁cache表。
- 如果采用开放寻址法使用的话,那么hash的查找效率可能就不高了,所以hash的效率还是极为关键的。
3. 线程模型
- 初始化主线程event_base,和worker线程
- 建立worker线程的通知管道
- 注册worker线程管道的libevent事件
- 初始化每个worker的CQ队列
- 启动worker线程,主线程监听socket事件,worker线程监听socket的读写事件
![](/assets/blank.gif)
二、Memcached的优化内容
1. 分块hash优化
- 首先把hash表分块,每个分块由不同的线程进行处理,当然可以绑定到固定的核上去,这个有个memc3就是这个绑定的
- 每个hash块拥有有自己的LRU表和hash的表,分块由自己的LRU和hash表进行处理操作
2. clock算法优化
目的其实很单纯,牺牲命中率和淘汰次数,提高get的读写性能,尤其是多核的情况下这个Clock置换算法大致描述如下
2类(A=0, M=1):表示该页最近未被访问,但已被修改,并不是很好的淘汰页。
3类(A=1, M=0):最近已被访问,但未被修改,该页有可能再被访问。
4类(A=1, M=1): 最近已被访问且被修改,该页可能再被访问。其执行过程可分成以下三步:
(1) 从指针所指示的当前位置开始,扫描循环队列,寻找A=0且M=0的第一类页面, 将所遇到的第一个页面作为所选中的淘汰页。在第一次扫描期间不改变访问位A。
(2) 如果第一步失败,即查找一周后未遇到第一类页面,则开始第二轮扫描,寻找A=0且M=1的第二类页面,将所遇到的第一个这类页面作为淘汰页。在第二轮扫描期间,将所有扫描过的页面的访问位都置0。
(3) 如果第二步也失败,亦即未找到第二类页面,则将指针返回到开始的位置,并将所有的访问位复0。然后重复第一步,如果仍失败,必要时再重复第二步,此时就一定能找到被淘汰的页。
- 只采用了时间进行标记,在update和get的时候记录下最新时间,在替换的时候检验这个时间是不是超期,如果超期则进行替换,如果没有超期就不替换。
- 为了能够支持循环查找,讲LRU的链表改成了双向的循环链表,同时添加hand指针,指向需要替换的元素,如果超期就替换,如果不超期则进行下一次尝试,如果失败的话,则就将这个元素替换出去
- 更新的过程中,不将元素放置到head处,只更新访问时间,这样的话就不用断掉链表,这样不用进行item _unlink和item_link的过程
3. hash算法优化
- 首先检测映射到的bucket,看它是不是被占用,如果未被占用那就直接使用
- 如果已被占用,那么采用线性探测法探测到位置pos
- 如果pos的位置离bucket的位置大于给定的阈值H,那就调整这个上面的位置,使得这个H-1的bucket上出现空槽,如果没有空槽,resize哈希表然后再次进行尝试。
4. tag查询优化
- 首先,另外采用一个hash函数计算算出一个1字节大小tag,直接保存在 hashtable 的对应item里面。
- 然后查找的时候,先比较tag是不是一致,如果一致,再去比较 key。
三、优化结果
[OVERALL], RunTime(ms), 45906.0
[OVERALL], Throughput(ops/sec), 108917.52712063782
[INSERT], Operations, 4999968
[INSERT], AverageLatency(us), 428.84410700228483
[INSERT], MinLatency(us), 123
[INSERT], MaxLatency(us), 59953
[INSERT], 95thPercentileLatency(ms), 0
[INSERT], 99thPercentileLatency(ms), 1
[INSERT], Return=0, 4999968
[OVERALL], RunTime(ms), 53169.0
[OVERALL], Throughput(ops/sec), 94039.15815606838[INSERT], Operations, 4999968
[INSERT], AverageLatency(us), 497.43873040787463
[INSERT], MinLatency(us), 120
[INSERT], MaxLatency(us), 156936
[INSERT], 95thPercentileLatency(ms), 0
[INSERT], 99thPercentileLatency(ms), 6
[INSERT], Return=0, 4999968
比较接近上限
[OVERALL], RunTime(ms), 77420.0
[OVERALL], Throughput(ops/sec), 64582.381813484884
[INSERT], Operations, 4999968
[INSERT], AverageLatency(us), 722.7500804005145
[INSERT], MinLatency(us), 120
[INSERT], MaxLatency(us), 118476
[INSERT], 95thPercentileLatency(ms), 1
[INSERT], 99thPercentileLatency(ms), 12
[OVERALL], RunTime(ms), 167550.0
[OVERALL], Throughput(ops/sec), 119367.16204118174
[READ], Operations, 19959611
[READ], AverageLatency(us), 389.58720097300494
[READ], MinLatency(us), 94
[READ], MaxLatency(us), 58364
[READ], 95thPercentileLatency(ms), 0
[READ], 99thPercentileLatency(ms), 3
[OVERALL], RunTime(ms), 168112.0
[OVERALL], Throughput(ops/sec), 118968.11649376607
[READ], Operations, 19960241
[READ], AverageLatency(us), 390.19616010648366
[READ], MinLatency(us), 97
[READ], MaxLatency(us), 166104
[READ], 95thPercentileLatency(ms), 0
[READ], 99thPercentileLatency(ms), 3
四、总结
Memcached哈希性能优化(八)——总结报告相关推荐
- MySQL性能优化(八):数据库性能诊断工具
一.mysqltuner.pl 1.1工具的下载及部署 解决环境依赖,因为工具是perl脚本开发的,需要perl脚本环境 yum install -y perl* 1.2下载脚本 在http://my ...
- 监控日志loging Elasticsearch(性能优化八)
在当今世界,各行各业每天都有海量数据产生,为了从这些海量数据中获取想要的分析结果,需要对数据进行提取.转换,存储,维护,管理和分析. 这已然远远超出了普通处理工具.数据库等的实现能力,只有基于的分布式 ...
- Android 性能优化 (一)APK高效瘦身
Android 性能优化 (一)APK高效瘦身 http://blog.csdn.net/whb20081815/article/details/70140063 Android 性能优化 (二)数据 ...
- Android 性能优化(三)布局优化 秒变大神
Android 性能优化 (一)APK高效瘦身 http://blog.csdn.net/whb20081815/article/details/70140063 Android 性能优化 (二)数据 ...
- Android 性能优化(五)ANR 秒变大神
Android 性能优化 (一)APK高效瘦身 http://blog.csdn.net/whb20081815/article/details/70140063 Android 性能优化 (二)数据 ...
- Android 性能优化lt;九 RecyclerView替代Listview用法
Android 性能优化 (一)APK高效瘦身 http://blog.csdn.net/whb20081815/article/details/70140063 Android 性能优化 (二)数据 ...
- 记一次接口性能优化实践总结:优化接口性能的八个建议
前言 最近对外接口偶现504超时问题,原因是代码执行时间过长,超过nginx配置的15秒,然后真枪实弹搞了一次接口性能优化.在这里结合优化过程,总结了接口优化的八个要点,希望对大家有帮助呀~ 数据量比 ...
- 完全优化MySQL数据库性能的八大巧方法
1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽 ...
- 罗海雄:仅仅使用AWR做报告? 性能优化还未入门(含PPT)
编辑手记:祝贺罗海雄老师加入Oracle ACE社区,他是数据库SQL开发和性能优化专家,也是ITPUB论坛的资深版主,我们整理了罗老师一篇AWR裸数据分析的文档,供大家学习参考(同款PPT和相关源码 ...
最新文章
- python 记录日志到日志服务器_Python日志模块的使用与思考:服务器程序将每日日志写入每日日志文件,logging,及,把,每天,到,当天,中...
- AJAX初探,XMLHttpRequest介绍
- AppStore 提供的App信息查询的WebService
- 用gameMaker做个小游戏
- vue 入口main.js 调用app.vue 入口页面以及触发第三方登陆校验
- Ruby实例方法和类方法的简写
- 四阶龙格库塔c语言,四阶龙格库塔算法的C语言实现
- Python3数据结构总结(列表list,元组tuple,集合set,字典dict,堆栈stack,队列queue和遍历技巧)
- Leetcode每日一题:108.convert-sorted-array-to-binary-search-tree(有序数组转成BST)
- JavaScript中实现深浅拷贝
- 怎么制作自己的数据集
- 语义分割学习总结(一)—— 基本概念篇
- 有了这个列表,程序员不愁没练手的小项目了
- Mysql复制原理以及流程
- 沙龙干货 Vol.1|如何让游戏广告收益不再艰难?演讲 PPT 免费领取!
- 减少mysql存储列的方法
- Svn 命令行工具 操作 SVN 服务器
- 游戏趣史:游戏引擎的发展史
- 如何通过微信创业赚钱
- Asp.Net使用加密cookie代替session验证用户登录状态 源码分享 欢迎拍砖