memcache源码分析系列三 assoc动态扩容

assoc动态扩容的条件:

现在的状态expanding是false,即没有进行扩容;并且item的个数大于hashsize(hashpower) 的1.5倍。

if (! expanding && hash_items > (hashsize(hashpower) * 3) / 2)

几个变量的含义:

expand_bucket 表示现在正在移动桶的序号。

old_hashtable 原先hash表的指针。

primary_hashtable 新hash表的指针。

#define hashsize(n) ((ub4)1<<(n)) 计算桶的个数
#define hashmask(n) (hashsize(n)-1) 计算位置的掩码

hashpower hash表的级别,级别越高,空间越大,默认是16,通过hashsize(hashpower)计算桶的空间。

expanding 是否正在扩容中。

动态扩容的步骤:

1.首先启动assoc_maintenance_thread线程,如果此时未在同步,则阻塞在maintenance_cond条件变量处。

2.当条件满足时,设置assoc_start_expand为true,并唤醒maintenance_cond条件变量条件变量。

3.设置锁粒度为全局锁,并通知各个线程;

调用assoc_expand函数重新给primary_hashtable分配原先两倍的内存,设置expanding为true,hashpower++;

4.继续while循环,加全局锁和cache_lock锁,

从0开始,到hashsize(hashpower - 1)依次移动每一个桶。

对于每一个桶,通过hash(ITEM_key(it), it->nkey) & hashmask(hashpower)计算key在新的空间内的位置。

5.当满足移动完成退出条件expand_bucket == hashsize(hashpower - 1)时,

释放原先old_hashtable hash表的空间。

6.释放cache_lock和全局锁。

7.扩容完成继续阻塞在maintenance_cond处,等待下一次扩容时再唤醒。

发现了一处问题:

1.全程锁引起的效率问题思考?

当扩容的时候,通知其他线程锁粒度是全局的。开始扩容加的是全局锁,扩容完成才会释放全局锁。

也就是说在扩容的过程中,其他线程对应的增删查改都不能进行。

默认hashpower是16,即2^16=65536,可以容纳65536个元素,当大于65536*1.5的时候就需要扩容。

越到后边要移动的数据越多,不知会不会影响效率。

想到的解决办法:在传入参入的时候,设置hashpower的大小,设的较大一些,这边要扩容的可能性越小。


几处知识点:

pthread_getspecific pthread_setspecific函数



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值