最近在监控上总是发现宿主机的load莫名的飙高,检查虚拟机负载也并没有异常,跟踪一段时间后发现,原来在load飙高的这段时间里,cinder-volume服务正在删除数据卷。排查日志,可以看到,当cinder-volume服务在处理删除卷的逻辑中,默认是对即将要删除的卷置零操作。
DEBUG oslo_concurrency.processutils [req-beeeb583-c07e-4f23-8b63-1f76fc729c9a 0a266a36e53e4469a376f5baa4375064 0a266a36e53e4469a376f5baa4375064 - default default] CMD "sudo cinder-rootwrap /etc/cinder/rootwrap.conf dd count=0 if=/dev/zero of=/dev/mapper/cinder--volumes-volume--beeeb583--c07e--4f23--8b63--1f76fc729c9a oflag=direct" returned: 0 in 0.127s execute /usr/lib/python2.7/site-packages/oslo_concurrency/processutils.py:374
从日志里面看到,volume服务调用dd命令对数据卷进行数据清空,同时采用oflag=direct参数直接操作块设备。所以,cinder在删除卷的时间长短和卷的大小有着直接关系。(删除期间iowait值会增高,怪不得load也会飙高)
那么,怎么解决cinder-volume服务在删除数据卷的时间过长,造成宿主机load飙高的情况呢。
可以从三个方面处理这个问题:
1. 关闭volume安全删除
# Allowed values: none, zero, shred
volume_clear = none
2. 置零volume头部100MB左右数据
# Size in MiB to wipe at start of old volumes. 0 => all (integer value)
volume_clear_size = 100
3. 调整dd进程io调度优先策略
OpenStack在Kilo版本之后添加volume_clear_ionice配置
# The flag to pass to ionice to alter the i/o priority of the process used to
# zero a volume after deletion, for example "-c3" for idle only priority.
# (string value)
volume_clear_ionice = -c3
K版本之前需要手动修改Cinder代码,如下
volume/utils.py
def _copy_volume(self, srcstr, deststr, size_in_g):
self._execute('ionice', '-c3', 'dd', 'iflag=direct', 'oflag=direct',
'if=%s' % srcstr, 'of=%s' % deststr,'count=%d' % (size_in_g * 1024),
'bs=1M', run_as_root=True)
关于删除卷的思考
之前不明白cinder在删除卷之前要对其做dd操作,这个过程又耗时又对服务器的负载造成影响。直到有次我在处理LVM的时候,发现即便在lvremove后重新lvcreate,新的lv里面还保留着老的数据,我才恍然大悟(只怪自己基础知识不牢固),原来直接删除lv并不会抹除卷上的数据。cinder之所以要用dd zero,就是为了避免租户A删除卷后,数据不会串到租户B新创建的数据卷上。这样一方面保证租户A的数据安全性,另一方面也避免租户B在使用数据卷的产生的疑惑。从cinder的配置文件可以看出,社区对于这类需求处理得还是很及时的。
那么实际环境下,我们改怎么选择配置,既保证数据的安全性,又尽量对服务器造成少的负载。
场景一. 保证数据绝对安全
volume_clear采用shred
永久删除,根据服务器情况适当调整volume_clear_ionice的值。
shred会用一些随机内容覆盖文件所在的节点和数据块,cinder在这里条用shred默认参数采用-n 3
即重写3次。
场景二. 数据相对安全的同时,降低数据卷删除时间
volume_clear采用zero
填充,根据情况设置volume_clear_size大小,我们都知道,磁盘的开头部分保存着文件系统的元数据以及索引,清空这部分可以一定程度上保证数据的安全。
至于volume_clear=none
这种直接删除lv而不清空数据的方式,我就不建议采用了,毕竟Cinder提供这么多配置选项来帮助我们减少数据卷删除时间,我们有何理由不用呢。
参考:
https://blueprints.launchpad.net/cinder/+spec/when-deleting-volume-dd-performance
https://review.openstack.org/#/c/74810/