Ceph pgid 转换计算

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ceph pgid 转换计算相关的知识,希望对你有一定的参考价值。

问题现象

最近调查一个ceph集群pg blocked IO/ slow request问题,发现集群出现短暂的blocked IO/ slow request,定位到日志发现在等待读写锁导致。查看当前集群负载,及前后日志均未发现异常,也没有慢盘情况。但有一个现象是操作前有deep-scrub 操作。猜测是PG deep 导致block IO。

问题原因

结合代码查看PG在做deep scrub时候确实会对chunk 加锁,导致IO下发到该PG内部的该chunk相关的对象读写阻塞,直到操作完毕,恢复读写;

pg id计算

以下是pg关键日志:

技术图片

我们可以很清楚的看到pg: 3.ad8 在做deep-scub操作,但是在出现slow request日志中,只能找到异常的对象rbd_data.xxx,甚至更详细的信息off-len,无法看到pg 3.ad8,这样就无法确认该对象发生在pg 3.ad8上

这里看到一个3.cc2fcad8 的字段,这个是本章介绍的重点。猜测这个 3.cc2fcad8 --- 3.ad8 存在映射关系。

其实ceph是通过C/S模式实现外部应用和内部集群之间的数据交互,这里对象是集群的基本单位,对象名字是rbd client负责生成,类似“rbd_data.xxx.xxxx”,计算出一个32位的哈希值(eg:cc2fcad8),然后根据对象的归属pool以及此哈希值,通过简单的取模计算,即可找到对应的PG。

pool id为3,查看该pool上有6030个pg,由于pg不是2的整数次方幂,向下取 2^(n-1)=4096

>python
>>> hex(0xcc2fcad8%4096)
‘0xad8‘

# hex 和 int函数是一个互逆函数;
>>> hex(255)
‘0xff‘
>>> int(0xff)
255
>>>

这里一般集群存储池pool的pg 是2的整数次方幂,此时计算直接 hex(0xcc2fcad8%pg_num) 即可,对于不是整数次方幂的情况,需要先向下取 2^(n-1),然后去计算。确保对象可以落在所有的pgid上。(其实对于非对齐方式,如果直接按照 2^n取模,会出现对象落在不存在pgid上的现象)

具体的计算方法:

if ((hash & (2^n -1)) < pg_num)
  return (hash & (2^n -1));
else
  return (hash & (2^n-1 -1))

以上是关于Ceph pgid 转换计算的主要内容,如果未能解决你的问题,请参考以下文章

CEPH PG数量设置

10个JavaScript代码片段,使你更加容易前端开发。

10个JavaScript代码片段,使你更加容易前端开发。

在代码片段中包含类型转换

sql 日期转换代码片段 - Dato,120,konvertere

【ceph】容量计算