11月 272018
 

ceph osd日志中显示,偶尔会收到来自于如下进程的信号:

如:

而且,通常出现在日志文件的第一条。

原因:

这个是 /etc/logrotate.d/ceph 中配置的用于切换日志文件的,没有其他影响

 

 Posted by at 上午 10:24
6月 262018
 

搭建openstack时,配置好rbd后,我们并没有在virsh pool-list 时看到一个存储池,但是如果我们要配置一个存储池也是可以的:

编写配置文件: rbd-volumes.xml

其中rbd-volumes是我们给这个存储池起的一个名字,随便你;

10.88.12.4 是ceph monitor节点地址

volumes 是rbd所在的ceph中的pool

auth里面有用户名cinder和预先定义好的秘钥(秘钥通过secret-define来定义)

 

然后执行:

 

然后就会自动生成文件 /etc/libvirt/storage/rbd-volumes.xml:

 

然后通过virsh pool-list 可以查看到定义好的存储池:

 

然后启动池子:

 

就可以列出来存储池中的rbd了;(我这里的volumes就是上面提到的rbd-volumes)

然后就可以使用这里的rbd来启动虚拟机了呗?不过又遇到问题,通过virt-manage来使用这里的rbd创建机器时报错:

话说这个和/root/volumes 有毛关系?

google 之,别人也有遇到: https://bugzilla.redhat.com/show_bug.cgi?id=1074169#c14

问题似乎出现在virt-manager 上,问题版本: 1.4.1 ; 换个新的试试:

https://github.com/virt-manager/virt-manager

更新到 1.5.0 依然存在这个问题,稍后再研究; 最新的版本构建起来麻烦一些,依赖python3的东西,我的安装源中有些找不到

 

相关fix: https://github.com/tonich-sh/virt-manager/commit/ce939a04099431ea273fa53850ab8a6db363a112

 

 

 

 Posted by at 下午 4:25
6月 132018
 

缘起:

为什么我执行ceph health时都是HEALTH_OK,但是搭建了Prometheus+grafana: (参考:https://www.2cto.com/net/201801/712794.html ),看到的状态却是HEALTH_WARN,why?

分析:

我们使用的ceph_exporter: github.com/digitalocean/ceph_exporter ; 参考源码发现,这里使用json格式获取的health,而且参考的是overall_status ; 自己在命令行看看:

果不其然,overall_status 为 HEALTH_WARN

办法一:

参考status,不参考overall_status;

缺点:

  1. exporter并没有收集status信息,只收集了overall_status ,如果要使用status,还得修改exporter
  2. HEALTH_WARN 毕竟是有问题,查明问题才是根本解决办法

办法二:

查明为什么overall_status 为HEALTH_WARN , 应该确实存在问题

 

查原因:

我的ceph版本: ceph version 12.2.1 (3e7492b9ada8bdc9a5cd0feafd42fbca27f9c38e) luminous (stable)

在 luminous 之前,ceph 输出的都是 overall_status , luminous开始,就开始使用status了,但是,为了兼容以前的版本,还是输出了overall_status了,不过,为了让使用者意识到 overall_status 不建议使用了,所以,就强制将 overall_status 设置为了 HEALTH_WARN; 有时候,这个逻辑显得不太友好,于是,从12.2.2 开始添加了一个选项:

可以通过设置该选项,来禁止这个警告。

但是,我使用的是12.2.1 ,咋办? 要么修改exporter,要么干脆升级ceph

比较稳妥的做法是,在一个测试的机器上,启动一个12.2.5版本的ceph-mon,设置:

然后,ceph.conf中指定连接该ceph-mon,测试效果如下:

没有了overall_status; 如此的话,ceph_exporter 就是要overall_status的话,还真就得修改ceph_exporter了, fork 后修改之:

https://github.com/phpor/ceph_exporter

 

参考:

https://github.com/ceph/ceph/pull/17930

http://lists.ceph.com/pipermail/ceph-users-ceph.com/2017-September/021031.html

 Posted by at 上午 10:01
3月 092018
 

语法说明

即: 选择 $n 个不同的bucket, 其中, $n = 0 意味着需要多少个副本就选择多少个bucket, $n = -1 意味着还需要选择多少副本就选择多少副本,返回结果是bucket,如果bucket 是osd自然就是叶子节点

 

即: 选择 $n 个不同的bucket,然后,再从每个bucket中任意选择一个osd,相当于:

 

这种情况下,显然chooseleaf比choose简单许多,表达的意思都是以bucket为故障域,在里面选择$n 个osd, 这也是比较常见的情况

 

情况二:

那么,如果我有多个row,但是期望将3份数据都存放在同一个row下,并且选择3个不同的rack存放呢?表达如下:

等价于:

 

情况三:

假如我有5个row,但是仅仅希望存储的两个副本分别存放在row1和row2(我们知道,每个bucket都是有名字的),而不是随意选择两个,然后以rack为故障域来选择osd,该如何写呢?

这时候,仅仅使用choose和chooseleaf就搞不定了,还记得take语法吧,如下:

 

 

参考:

 Posted by at 下午 5:03
3月 072018
 

现象:

 

分析:

  1. 哪个pool的问题?
  2. 原因: 某个pool中单个pg的对象数量超过了集群每pg对象数量平均值的10倍; 并不意味着肯定是有问题的
  3. 重现方法:只要你的集群中至少有一个pg是较多使用的,那么你再多创建几个pool,pg设置的大一些,这个报警就可以出现

解决办法:

  1. 删掉没用的pool,或者:
  2. 调整参数:
    1. 如下: (需要重启)
  3. 调整报警的pool的pg数量

 

思考:

  1. 既然pg中对象太多就会报警,那么,创建pool时就指定一个较大的pg值(如: 1024)不就可以了? 这样也不行,pg数量太大,理论上会影响性能,而且,单个osd上pg数量太多(超过mon_pg_warn_max_per_osd) 也会报警: http://blog.csdn.net/styshoo/article/details/62722679 查看每个osd上pg数量的方法:

    然而,我的osd上的pg数量也超过了300的设置值了,没有报警呢
  2. 具体需要调整的选项需要参考对应版本的文档或代码,如,12.2.1 的release notes 中就有这样的说明:
    The maximum number of PGs per OSD before the monitor issues a warning has been reduced from 300 to 200 PGs. 200 is still twice the generally recommended target of 100 PGs per OSD. This limit can be adjusted via the mon_max_pg_per_osd option on the monitors. The older mon_pg_warn_max_per_osd option has been removed.

 

参考:

 Posted by at 上午 10:09
3月 062018
 

缘起:

使用dd读取一个大文件时,速度可达 100MB+/s, 但是cat读取大文件时,速度才达到 30MB/s,为何?

由于ceph块儿设备是从网络上读取数据,读取数据的效率和网络的性能由于直接关系,同时也和每次读取的块儿的大小有直接关系:

在块儿大小为100MB的情况下,读取速度可达到 120MB/s

在块儿大小为1MB的情况下,读取速度可达到 70MB/s

在块儿大小为64KB的情况下,读取速度可达到 30MB/s; ,然而cat命令每次read的大小正好是64KB

针对这种情况,如果本机有较大内存的话,不妨先通过dd大块儿的方法使得文件被cache起来,然后再做其它类似cat的操作;

 

另外: 增加IO大小,到达底层之后,会变成多个IO请求,相当于底层同时又多个IO请求,实际上是相当于增加了队列深度。

 Posted by at 下午 6:23
3月 062018
 

通过命令行创建纠删码规则

  • 首先,需要创建 erasure-code-profile ,当然,也可以使用默认的 erasure-code-profile ,列出现有的 erasure-code-profile :
  • 查看指定erasure-code-profile 的详细内容:
  • 自定义erasure-code-profile , 创建一个只用hdd的 erasure-code-profile:

    可用的选项有:

    • crush-root: the name of the CRUSH node to place data under [default: default].
    • crush-failure-domain(故障域): the CRUSH type to separate erasure-coded shards across [default: host].
    • crush-device-class(设备分类): the device class to place data on [default: none, meaning all devices are used].
    • k and m (and, for the lrc plugin, l): these determine the number of erasure code shards, affecting the resulting CRUSH rule.
  • 根据erasure-code-profile 创建crush rule:
  • 查看crush rule:
  • 创建一个使用纠删码规则的pool

    语法: osd pool create <poolname> <int[0-]> {<int[0-]>} {replicated|erasure} [<erasure_code_profile>] {<rule>} {<int>}
    尽管crush rule 也是根据erasure_code_profile来创建的,但是这里创建纠删码pool的时候,还是需要明确指定erasure_code_profile
    参考: http://docs.ceph.com/docs/master/rados/operations/pools/
  • 调优:

    目前,这个fast_read 之针对纠删码池有效的
  • 如果需要在该pool创建rbd,则需要:
    • 参考: http://docs.ceph.com/docs/master/rados/operations/erasure-code/
    • 创建一个replication pool来做cache tier

      其实,不仅纠删码池可以做cache tier,replication 池子也能做cache tier,因为,我们可能有一批ssd盘,我们就可以在ssd上创建pool来充当sas盘的cache tier以提高性能;结合纠删码、replication、sas、ssd,我们可以做出多种不同性能的存储用以应对不同的场景。
    • 然后 ceph 会提示: 1 cache pools are missing hit_sets  , 还要设置 hit_set_count 和 hit_set_type

通过编辑crushmap来添加规则

参考:

 

实战中的问题:

  1. 12个SAS在 60MB/s 的速度evict的时候,磁盘都很慢了,每个盘达到100左右的tps, 20MB/s左右的读写;比较坑的是,我基本没法控制evict的速度,只好静静地等待evict结束
  2. evict 的同时还在promote, promote的速度倒是可控,但是 osd_tier_promote_max_bytes_sec 默认是5242880 字节(并不算很大); 问题:池子已经没有写入了,为何还在evict和promote?
  3. 修改cache-mode试试: 按说,修改cache-mode为proxy时,就不应该再出现evict和promote了

    果然,修改之后,ceph -s 立刻就看不到evict和promote了 🙂
  4. 查看cache-mode:

 Posted by at 下午 5:01
2月 072018
 

每个kvm虚拟机进程,如果挂载N个rbd设备,则会有N个 fn-radosclient 线程,每个fn-radosclient 线程针对特定的osd只有一个connection; 如此,一个rbd设备上的某块儿数据如果落在了相同的osd上,(猜测rados协议不会再同一个连接上同时做多个事务),则意味着不可能并行写入,于是乎,特别是对于随机读写,网络延迟对存储效率有着直接的影响,即使虚拟机内部多线程也无济于事,因为kvm进程中的fn-radosclient 只有一个

 

 

 Posted by at 下午 5:42
1月 052018
 

缘起:

20T的1亿个小文件存放在xfs的文件系统中会存在inode被用光(但是存储空间还有很大空闲)的问题吗?

 

测试:

df -i 可以看到可用、已用inode数量,一般来讲,mkfs的时候,会划分 x% 的空间存放inode的,可用inode数量是按照文件个数计算的,不是按照占用空间计算的,如:

500GB的磁盘,格式化为xfs后,可以使用的inode数量约 2.6亿; 那么1GB的磁盘格式化为xfs后,可用inode数量为 2.6亿/500 ~= 50万吗?测试如下:

确实,1GB默认可以存放约52万个文件,注意: 目录也是占用inode的,而且也不可能把所有文件都放在一个目录的,所以真正计算inode的话,还需要把目录的数量算上; 按照每个目录100个文件计算的话,50万个文件就需要5k个目录(可以忽略不计了);其实不全对,5k个目录放在一个父目录下也不科学,为了保证每个目录最多100个的话,还要分到50个父目录里面,额.. 也没有多少目录

 

按照上面的公式计算: 20T/1G*50w ~= 1000亿 个文件, 不少了

当然,如果还不够的话,格式化的时候可以指定更大的inode数量

 

计算:

10亿个文件,打散到N个目录中,每个目录的子目录(文件)数量不超过100个,需要多少级子目录?

100x  > 10亿 ,x最少值为 x>=5 ,就是说 5层目录就够了

 


其实,xfs是个比较只能的文件系统,没有固定大小的inode区域,随着磁盘的使用,inode的总数量也在变化,基本不会出现inode已用光,但是存储空间很空闲很多的情况

 Posted by at 下午 4:42