Ceph Observer动态更新配置参数
来源:互联网 发布:51单片机da转换 编辑:程序博客网 时间:2024/06/04 17:57
ceph Observer(观察者模式),可以动态的更改系统配置参数,而不需重启服务。
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();}
0 0
- Ceph Observer动态更新配置参数
- ceph配置参数
- Ceph配置参数分析
- ceph存储 ceph集群配置参数一
- ceph存储 ceph集群配置参数二
- ceph存储 ceph集群配置参数三
- Ceph配置参数(一)
- Ceph配置参数(二)
- Ceph配置参数(三)
- jquery uploadify动态更新配置参数方法uploadifySettings()
- Ceph配置
- Ceph性能优化 之 配置参数调优
- ceph存储 ceph集群配置
- ceph ceph.conf 配置流程
- log4j动态配置参数
- ceph recovery 参数调研
- Ceph集群配置-----2.ceph配置
- 动态修改MYSQL配置参数
- poj 3468(线段树,splay tree)
- Glusterfs之小文件优化
- 编译openface代码遇到问题及解决方法
- WiFi探针可以运用于哪些领域?
- POJ2926-Requirements,曼哈顿距离。去掉绝对值符号暴力枚举所有情况,神薙!
- Ceph Observer动态更新配置参数
- Android Logger日志框架实现
- Android项目重构之路:架构篇
- 屏幕特效插件分析——FxPro & Beautify
- c语言字符串快速排序qsort()
- HTTPS大势已来?看腾讯专家如何在高并发压测中支持HTTPS
- Spring学习笔记(5.Spring Bean装配之Bean的配置项及作用域)
- Linux常用命令学习二
- 模仿与学习MyBatis - 实现自己的ORM层框架