Ceph Observer动态更新配置参数
2016-12-05 17:20
876 查看
ceph Observer(观察者模式),可以动态的更改系统配置参数,而不需重启服务。
//将观察者与其观察的key放入observer中。
//将制定的观察者从observers集合中去除
//获取observer的配置参数集,不同的的子系统实现不同
//更新全局配置参数,然后把发生变动的参数的key放入到changed集合中
//配置参数集合大致可以分为两类,一:与子系统相关的日志级别参数、二: 普通服务配置参数
md_config_t: //multimap 类型key为option,value为关注该可以的对象。 observers (typedef std::multimap <std::string, md_config_obs_t*> obs_map_t) //发生变动的option changed (typedef std::set < std::string >)
//将观察者与其观察的key放入observer中。
void md_config_t::add_observer(md_config_obs_t* observer_) { Mutex::Locker l(lock); const char **keys = observer_->get_tracked_conf_keys(); for (const char ** k = keys; *k; ++k) { obs_map_t::value_type val(*k, observer_); observers.insert(val); } }
//将制定的观察者从observers集合中去除
void md_config_t::remove_observer(md_config_obs_t* observer_) { Mutex::Locker l(lock); bool found_obs = false; for (obs_map_t::iterator o = observers.begin(); o != observers.end(); ) { if (o->second == observer_) { observers.erase(o++); found_obs = true; } else { ++o; } } assert(found_obs); }
//获取observer的配置参数集,不同的的子系统实现不同
get_tracked_conf_keys()
//更新全局配置参数,然后把发生变动的参数的key放入到changed集合中
//配置参数集合大致可以分为两类,一:与子系统相关的日志级别参数、二: 普通服务配置参数
//set_val()->set_val_impl()->set_val_impl() int set_val(const char *key, const string& s, bool meta=true, bool safe=true) { return set_val(key, s.c_str(), meta, safe); } int md_config_t::set_val(const char *key, const char *val, bool meta, bool safe) { Mutex::Locker l(lock); if (!key) return -EINVAL; if (!val) return -EINVAL; std::string v(val); if (meta) expand_meta(v, &std::cerr); string k(ConfFile::normalize_key_name(key)); // subsystems? if (strncmp(k.c_str(), "debug_", 6) == 0) { for (int o = 0; o < subsys.get_num(); o++) { std::string as_option = "debug_" + subsys.get_name(o); if (k == as_option) { int log, gather; int r = sscanf(v.c_str(), "%d/%d", &log, &gather); if (r >= 1) { if (r < 2) gather = log; // cout << "subsys " << subsys.get_name(o) << " log " << log << " gather " << gather << std::endl; subsys.set_log_level(o, log); subsys.set_gather_level(o, gather); return 0; } return -EINVAL; } } } for (int i = 0; i < NUM_CONFIG_OPTIONS; ++i) { config_option *opt = &config_optionsp[i]; if (strcmp(opt->name, k.c_str()) == 0) { if (safe && internal_safe_to_start_threads) { // If threads have been started... if ((opt->type == OPT_STR) || (opt->type == OPT_ADDR) || (opt->type == OPT_UUID)) { // And this is NOT an integer valued variable.... if (observers.find(opt->name) == observers.end()) { // And there is no observer to safely change it... // You lose. return -ENOSYS; } } } return set_val_impl(v.c_str(), opt); } } // couldn't find a configuration option with key 'key' return -ENOENT; } int md_config_t::set_val_impl(const char *val, const config_option *opt) { assert(lock.is_locked()); int ret = set_val_raw(val, opt); if (ret) return ret; changed.insert(opt->name); return 0; } int md_config_t::set_val_raw(const char *val, const config_option *opt) { assert(lock.is_locked()); switch (opt->type) { case OPT_INT: { std::string err; int f = strict_si_cast<int>(val, &err); if (!err.empty()) return -EINVAL; *(int*)opt->conf_ptr(this) = f; return 0; } case OPT_LONGLONG: { std::string err; long long f = strict_si_cast<long long>(val, &err); if (!err.empty()) return -EINVAL; *(long long*)opt->conf_ptr(this) = f; return 0; } case OPT_STR: *(std::string*)opt->conf_ptr(this) = val ? val : ""; return 0; case OPT_FLOAT: { std::string err; float f = strict_strtof(val, &err); if (!err.empty()) return -EINVAL; *(float*)opt->conf_ptr(this) = f; return 0; } .... case OPT_UUID: { uuid_d *u = (uuid_d*)opt->conf_ptr(this); if (!u->parse(val)) return -EINVAL; return 0; } } return -ENOSYS; }
void md_config_t::apply_changes(std::ostream *oss) { Mutex::Locker l(lock); _apply_changes(oss); } void md_config_t::_apply_changes(std::ostream *oss) { /* Maps observers to the configuration options that they care about which * have changed. */ typedef std::map < md_config_obs_t*, std::set <std::string> > rev_obs_map_t; expand_all_meta(); // create the reverse observer mapping, mapping observers to the set of // changed keys that they'll get. rev_obs_map_t robs; std::set <std::string> empty_set; char buf[128]; char *bufptr = (char*)buf; //将更新后的配置参数与oberver相关联。 for (changed_set_t::const_iterator c = changed.begin(); c != changed.end(); ++c) { const std::string &key(*c); if ((oss) && (!_get_val(key.c_str(), &bufptr, sizeof(buf))) && !_internal_field(key)) { (*oss) << key << " = '" << buf << "' "; } pair < obs_map_t::iterator, obs_map_t::iterator > range(observers.equal_range(key)); for (obs_map_t::iterator r = range.first; r != range.second; ++r) { rev_obs_map_t::value_type robs_val(r->second, empty_set); pair < rev_obs_map_t::iterator, bool > robs_ret(robs.insert(robs_val)); std::set <std::string> &keys(robs_ret.first->second); keys.insert(key); } } // Make any pending observer callbacks //调用observer的回调函数handle_conf_change() 更新系统参数。 for (rev_obs_map_t::const_iterator r = robs.begin(); r != robs.end(); ++r) { md_config_obs_t *obs = r->first; obs->handle_conf_change(this, r->second); } changed.clear(); }
相关文章推荐
- jquery uploadify动态更新配置参数方法uploadifySettings()
- uploadify动态更新配置参数方法uploadifySettings()报错“updateSettings is not a function”之解决办法
- 在 Windows 2003 中配置 DNS 动态更新
- C#2005 动态修改配置参数
- Handler传递参数动态更新UI界面demo
- pfile spfile静态和动态修改配置参数
- MSVC 2012以及Mingw动态编译及静态编译 QT 5.0.2/5.4.0,附上Linux编译QT 5.4.1的配置参数
- Castle ActiveRecord 使用动态填写参数方式配置数据库连接
- 动态修改MYSQL配置参数
- MySQL系统配置参数优化总结【持续更新中】
- mysql 动态修改配置参数
- mysql中max_allowed_packet参数的配置方法(避免大数据写入或者更新失败)
- ini文件动态配置程序参数
- Cognos学习之四:Cube性能优化、参数配置和更新
- 在LINUX上动态配置核心参数
- DB2动态配置参数(Linux)
- 动态修改MYSQL配置参数
- Castle ActiveRecord 使用动态填写参数方式配置数据库连接
- 通过环境变量设置WEB项目数据源(Spring)及其项目配置文件路径,动态更新数据源及项目配置
- mysql中max_allowed_packet参数的配置方法(避免大数据写入或者更新失败)