hash 值重复_MySQL查询缓存hash算法优化

上一篇,我们总结了QC的主要瓶颈在:QC锁竞争;表的permission check锁竞争;查询时Hash碰撞。

因此,就可以初步决定了我们的优化方向:QC锁优化,表permission check的锁优化(不能影响Buffer pool),Hash碰撞的优化。

本篇我们尝试在Hash碰撞上面进行优化。

MySQL原生Hash算法行

MySQL的的原生Hash算法,是在http://Sql_cache.cc中的init_cache方法中进初始化的:

图1 hash算法初始化的地方

继续跟踪查找后,看到实际上调用了_my_hash_init方法,其中hash->hash_function就是初始化算法的地方,如果没有自定义,则会使用cset_hash_sort_adapter这个方法。在向其中查找,最终可以找到默认的hash方法是ctype-bin.c文件中的my_hash_sort_bin方法

图2 原始的hash算法

这是普通的字符串Hash算法,这种算法过于简单,重复率非常高;比如使用Aurora的测试模型时,碰撞率非常高,一次my_hash_search需要查找40+次,因此才会出现上期所说hash碰撞问题。那么有没有好的Hash算法,可以降低碰撞率呢?这里就要介绍一下MurmurHash算法

MurmurHash是高运算性能,低碰撞率,由Austin Appleby创建于2008年,现已应用到Hadoop、libstdc++、nginx、libmemcached, redis等开源系统。2011年Appleby被Google雇佣,随后Google推出其变种的CityHash算法

MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。 由Austin Appleby在2008年发明, 并出现了多个变种,都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。---摘自wiki

具体的算法各位可以在网上查到,说明很多,本文具体说明如何修改源码。

添加新的Hash算法

在sql_cache.h文件中新增hash算法:

图3 算法

图4 另外加上入口

修改注册算法

在http://sql_cache.cc文件中,添加注册hash的handler

图5 需要注册的hash handler

然后修改文章开头提到的my_hash_init方法所在的地方:

图6 修改注册的地方

注意这里使用了my_hash_init3这个宏,大家可以看到,实际上都是调用了_my_hash_init方法,只是入参不同。这里使用第三个宏,才可以吧自己的方法注册进去。

另外这里还要非常住一个值的修改:图5中QUERY_CACHE_DEF_QUERY_HASH_SIZE这个参数,默认是1024,这里改为200000。通过算法可以看到最终的hash值如果跟1024取余的话,那相当于只有1024种取值,那么碰撞会非常大。笔者在这里踩了1个多小时的坑,刚修改完hash算法后,bench mark越跑越低。

以上代码修改完成后,编译运行,来对比下优化前和优化后的数据:

图7 优化前

图8 优化后

从以上数据对比可以看到:优化前只有6500~6600左右的纯读QPS,跑久了也就7000左右;而优化后,已经到1W左右的QPS,一个小小的改动,提升了将近50%的性能!

再来看下是否真的是hash算法消耗的时间降低了呢?

图9 优化前的my_hash_search消耗时间占比

图10 优化后的my_hash_search消耗占比

从图9和图10的对比中我们可以看到,my_hash_search方法消耗的时间占比大大降低,同时读时延也大大减少。新的hash算法带了较低的hash

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值