Ceph配置项动态变更机制浅析

转自:https://www.ustack.com/blog/ceph%e9%85%8d%e7%bd%ae%e9%a1%b9%e5%8a%a8%e6%80%81%e5%8f%98%e6%9b%b4%e6%9c%ba%e5%88%b6%e6%b5%85%e6%9e%90/

OpenStack做一个log级别的变更就得重启,很耗费时间。本篇主要是向大家介绍一下ceph tell是如何便捷地实现log级别的变更的,并展开来介绍Ceph是如何动态管理配置项的。Ceph tell命令tell命令能够让你在一台主机上操作所有的osd,会对运维工作带来很大的便利,首先来看一下ceph tell都能做哪些事情呢?

 

ceph111我们再来看看tell是怎么做到的,这里我们将主要精力放在osd的injectargs上面(因为能够动态改变配置),其它的都可以,以此类推。简单的说在osd启动的时候会初始化一些工作队列,也就是wq,而其中一个就是command_wq,该队列的处理函数主要是调用do_command函数,在该函数中对injectargs的处理是调用md_confit_t 的apply_changes,最终是调用注册的观察者,来对改变的配置做出响应。可以从以下三个方面展开来分析:

1、配置存放在哪里?

在osd启动的时候会初始化两个全局的指针g_ceph_context和g_conf。g_ceph_context是CephContext *的类型,g_conf是md_config_t*的类型。它们的关系是g_conf = g_ceph_context->_conf 。在初始化osd之前就会将g_ceph_context和g_conf给准备好,g_conf会从配置文件,环境变量,和命令行参数三个地方来初始化全局配置。这样为后续的操作做好准备。比如data目录,journal目录,osd的网络都需要从g_conf里读取。所以在osd init之前必须得把g_conf给准备好。
g_conf里配置项的内容是从配置文件解析得到的,首先会检查有没有设置环境变量$CEPH_CONF,然后再依次从$data_dir/config, /etc/ceph/$cluster.conf, ~/.ceph/$cluster.conf, $cluster.conf”;来读取配置,如果在前一个位置有配置,就会读取并解析,不会再去后面读取。所以不会出现前面的覆盖后面的情况。

2、配置的更新是如何做到的?

首先每一个osd都继承了md_config_obs_t类,md_config_obs_t 就是md_config_t的一个观察者,其关注的对象可以通过get_tracked_conf_keys()这个虚函数来获取到。OSD在pre_init的时候,将自己注册到md_confit_t的观察者map中,当md_confit_t apply_change的时候,会找到哪些观察者对要更新的参数感兴趣,然后就调用这些观察者的handle_conf_change()。从而实现obs状态的更新。具体到每一个obs,会根据不同的配置项调用相应的set方法,来完成配置项的更新。这里看一点代码应该就更清楚了。

ceph2222

从上面可以看到如果inject的参数没有观察者对其感兴趣,则你是没有办法改变的,而且会给你提示。但是conf确实发生了变化,只不过这个变化没有生效而已。

ceph333

这里总结tell的流程如下:

ceph444

3、关于配置项

从conf_opts.h文件来看,配置项主要有两类:一类是SUBSYSTEM的,一类是OPTION。
SUBSYSTEM主要定义了日志子系统写日志的级别。OPTION则主要定义了特定配置项的类型和初始的值。当injectargs的时候可以通过–debug_${system}=int/int 来改变子系统日志的级别。

总结

本篇从tell 命令出发,详解介绍了和osd相关的tell命令,然后深入到osd的配置管理中,讲述了Ceph是如何通过injectargs来实现动态改变配置的。

posted @ 2017-03-24 11:35  gold叠  阅读(2119)  评论(0编辑  收藏  举报