OpenStack Ceilometer用MongoDB解决占用磁盘空间过大问题

OpenStack Ceilometer用MongoDB解决占用磁盘空间过大问题

背景:Ceilometer使用MongoDB作为数据库,不断进行采样,导致数据量膨胀,占用过多的磁盘空间。

知识背景

1.数据库文件类型

1.1. journal 日志文件

跟一些传统数据库不同,MongoDB的日志文件只是用来在系统出现宕机时候恢复尚未来得及同步到硬盘的内存数据。日志文件会存放在一个分开的目录下面。启动时候MongoDB会自动预先创建3个每个为1G的日志文件(初始为空)。

1.2. namespace 表名文件 dbname.ns

这个文件用来存储整个数据库的集合以及索引的名字。这个文件不大,默认16M,可以存储24000个集合或者索引名以及那些集合和索引在数据文件中得具体位置。通过这个文件MongoDB可以知道从哪里去开始寻找或插入集合的数据或者索引数据。

1.3. 数据文件 dbname.0, dbname.1,… dbname.n

MongoDB的数据以及索引都存放在一个或者多个MongoDB数据文件里。第一个数据文件会以“数据库名.0”命名,如 my-db.0。这个文件默认大小是64M,在接近用完这个64M之前,MongoDB 会提前生成下一个数据文件如my-db.1。数据文件的大小会2倍递增。第二个数据文件的大小为128M,第三个为256M。一直到了2G以后就会停止,一直按这个2G这个大小增加新的文件。

2.数据库大小参数

2.1. dataSize

dataSize是最接近真实数据大小的一个参数。你可以用来检查你的数据有多少。这个大小包括了数据库(或者集合)的每条记录的总和。注意每条记录除了BSON文档外还有header及padding这些额外开销。所以实际大小会比真正数据所占空间会稍大。

2.2. storageSize

这个参数等于数据库或者某个集合所有用到的Data Extents的总和。注意这个数字会大于dataSize因为Extent里面会有一些删除文档之后留下来的碎片。如果有新插入的文档小于或等于碎片的大小,MongoDB会重新利用这个碎片来存储新的文档。不过在这之前这些碎片将一直会被保留在那里占用空间。由于这个原因,你删除文档的时候这个参数不会变小。

2.3. fileSize

这个参数只在数据库上有效,指的是实际文件系统中用到的文件的大小。它包括所有的数据Extents的总和,索引Extent的总和,以及一些未被分配的空间。之前提到MongoDB会对数据库文件创建时候进行预分配,例如最小就是64M,哪怕你只有几百个KB的数据。所以这个参数可能会比实际的数据大小会大不少。 这些额外未用空间是用来保证MongoDB可以在新的数据写入时候快速的分配新的Extent,避免引起磁盘空间分配引起的延迟。

解决方案

1.减少预分配的大小(或禁用预分配)

从MongoDB的预分配机制考虑,可以减少预分配的大小,或者禁用预分配。但是这种方案是会影响数据库行为的。如果数据库没有频繁的大数据写入动作,可以采取这种方案。

2.数据压缩

conpact命令可以对collection进行压缩,从而减少数据量的大小。

db.runCommand({compact:'CollectionName'})

这里需要注意的是:

1)操作进行时,会锁住当前操作的collection;
2)compact命令不会释放磁盘空间的,但新的磁盘请求会使用整理出来的空间;

3.将数据导出再导入

mongodump作用是将数据库导出,mongorestore是将导出的数据库再导入,这个过程中会重建索引,所以如果数据库之前进行过删除操作,空间没有释放,那么导入后,删除的空间会被释放。

4.定期删除不用的数据

结合实际情况,ceilometer采取的sample在有效期过后是可以被消除的。

步骤:

1)通过改变/etc/ceilometer/ceilometer.conf的time_to_live参数指定sample的有效期;
2)运行ceilometer-expirer删除过期的sample;
3)重启openstack-ceilometer-collector服务;
4)删除后,使用repairDatabase修复数据库。

注意,repairDatabase操作所需要磁盘的空余空间为当前数据总量再加上2G。如果当前磁盘分区空间不足,可以尝试用 –repairpath 参数指定一个空间足够的分区路径。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!