1 项目概述
1.1 背景介绍及目标
1.1.1 背景
(1) 配置管理是 PAAS 服务的基础组件,是业务迭代的重要组成部分,目前存在如下问题:
无配置分发机制
无配置检查流程
无配置变更记录
(2) 巡检(监控)数据存储,目前巡检存储在 Redis 中,目前存在如下问题:
无数据存储历史(每天巡检时清空之前数据,然后存储当天数据)
查询数据时,数据列表索引存储在 set 类型中,目前是全量拉取数据,前端渲染耗时长
1.1.2 目标
解决配置 / 巡检(监控)等多种业务场景数据存储问题
解决配置的管理、存储、发布问题
针对配置的版本管理、存储、查询、修改进行设计
提供配置的文件级的依赖管理,提供配置文件变更的触发机制
1.2 名词说明
section: 存储数据模板
instance: 存储数据记录
item: 存储数据值
1.3 Roadmap
一期:(2021-01-30)
二期:
section 与状态机绑定,item 变更触发事件
通过星桥触发配置更新及配置分发操作
2 需求分析
2.1 功能需求
(1) 多种业务场景(含有巡检(监控)类数据,配置类数据)
(2) 数据类型多
(3) 可以查询数据变更情况(巡检类数据)
(4) 可以通过配置进行反查对应服务
2.2 非功能需求
2.3 调研
2.3.1 业界方案
Facebook 配置中心
2.3.2 OSP 平台
配置创建
所谓配置其实就是 "应用程序的变量", 和应用程序息息相关
当我们发布了程序包时,也会有对应需要的配置文件生成,即配置是和发布包绑定的
确定了应用程序包对应配置的默认值
确定了应用程序包涉及哪些配置(不同的版本间可能会增减)
通过 name
, program
, version
联合主键来标记配置唯一性
config_item
例子 (twemproxy)
配置存储
redis
每个 service 的配置使用 hash 结构进行存储
直接获取配置(所有配置 value 都是字符串形式)
配置生成
程序中含有初始默认配置,通过程序进行生成默认配置和修改配置
2.3.3 SCS 简单配置生成
template + (user config)
部署包(package) 关联 template(版本)
部署包版本与配置版本不是一一对应
Config
服务配置文件(可能有多个配置文件)
Agent 配置文件(监控、日志采集等 agent)
Auth
ACL 文件
Whitelist 文件(IP、CIDR) 等
Auth 配置
3 总体设计
3.1 系统架构
3.2 模块简介
五行整体分为三个模块
wuxing 为业务逻辑模块
MySQL 存储 wuxing 数据
Redis 存储 wuxing 缓存
3.3 设计与折衷
3.3.1 配置发布方式
(1) 基本的 KV + 模板生成配置
例如可以使用 butterfly 自带的模板功能渲染文件
(2) 基本的 KV + 本地的生成脚本进行生成配置
五行偏向于数据的管理,弱化配置管理的模板功能,故选择方案二
五行中可以新增 template 表,存储配置模板
模板与 section 关联,可以添加一个参数判断是否获取渲染文件
如果需要获取渲染文件,则根据 section 关联的 template 进行渲染生成
3.3.2 配置版本管理
(1) 版本号方式
(2) 操作历史方式
折衷分析:使用方案一时,遇到列表展示等需求时不太好实现,故使用"操作历史方式"
3.3.3 存储 key 的类型
zabbix 的 key 类型
类似的配置 / 属性中也可以存储下浮点数,字符,数字三种类型
wuxing_float
wuxing_uint
wuxing_str
这样可以直接使用数据用于统计使用,变更历史可以为:
wuxing_history_float
wuxing_history_int
wuxing_history_str
wuxing_history_bool
折衷考虑,item 存储在一张表中方便管理,故 item value 数据会存储在 wuxing_instance_item 中,item 的历史记录会存储在 wuxing_history_{value type}
中
3.3.4 item 与状态机关联
(1) section 模板中指定状态机
(2) instance_update_item 时,指定状态机
(3) instance_update_item 时,指定是否使用状态机
根据约定优于配置,配置优于实现原则,(3) > (2) > (1) 故选择方案 (3)
实现方式还在调研中
3.3.5 item 与触发器关联
状态机模式关联 item 后,可以限制 item_value 在有限 value 间进行流转
如果存储的是巡检类数据的话,则数据不是固定的,需要在特定条件下进行触发事件,这个业界可参考的方案很多,比如 Zabbix/Nagios/Open-Falcon/Prometheus
(1) zabbix 方式
3.3.6 value 限制
规则1 若type==1单选
用|切分conf-range形成list1
判断目标值是否在list1中
规则2 若type==2 数字
判断目标参数值是否为数字
用-切分conf-range,与目标值比大小(左闭右闭)
规则3 若type==3 多选
用|切分conf-range形成list1
用,切分目标值形成list2
判断list2中元素都在list1中
3.3.7 配置分发机制
TODO: service 对应多个配置文件
3.4 潜在风险
4 详细设计
4.1 交互流程
4.1.1 section
4.1.1.1 增
创建 section(section_create)
4.1.1.2 删
删除 section(section_delete)
4.1.1.3 改
section 模板中添加 item(section_item_add)
section 模板中删除 item(section_item_delete)
启用 section(section_enable)
4.1.1.4 查
section 列表 (section_list)
section 详情 (section_get)
4.1.2 instance
4.1.2.1 增
4.1.2.2 删
4.1.2.3 改
更新 item 值
更新 section 版本
4.1.2.4 查
列表
详情
4.1.3 item
4.1.3.1 增
备注
4.1.3.2 删
备注
4.1.3.3 改
4.1.3.4 查
4.2 数据库设计
4.2.1 表之间关系
4.2.2 表详情
4.2.2.1 section
表名:wuxing_section
4.2.2.2 instance
表名:wuxing_instance
4.2.2.3 item
表名:wuxing_instance_item
4.2.2.4 item history
表名:wuxing_history_bool
表名:wuxing_history_float
表名:wuxing_history_int
表名:wuxing_history_string
表名:wuxing_history_text
4.3 接口
5 使用实践
5.1 命名方式
namespace(最多 16 个字符): 会表明是哪个模块在使用,此数据是监控类数据还是配置类数据,可以通过 "app_分类_功能" 进行划分,比如:
m(监控 / 巡检类数据),c(配置类数据),s(统计类数据)
例子
bq_m_conf:(表示扁鹊配置检查类数据)
bq_m_state:(表示扁鹊运行状态类数据)
bq_m_entry:(表示扁鹊入口检查类数据)
qn_c_global:(表示青囊全局配置)
qn_c_cluster:(表示青囊集群配置)
xh_s_resource:(表示星河资源统计)
section(最多 64 个字符): 可以通过 "level_module" 进行划分
例子
pool_redis(全局)
group_redis(redis 集群)
service_proxy(proxy 组件)
service_redis(redis 组件)
unit_proxy(redis 实例)
section level
5.2 已有表如何进行转换为五行方式
表 + 单个主键
5.3 section 与 instance 列表展示
5.4 表限制
namespace: (string) 16 个字节限制
section_name: (string) 64 个字节限制
section_version: (string): 16 个字节
instance_name: (string) 64 个字节
section_template: (string) 4k 字节
instance_template: (string) 4k 字节
5.5 cache
6 部署
https://github.com/meetbill/butterfly/wiki/wuxing_ha
7 接入五行例子
7.1 【星河】统计各机房资源池信息
namespace:section_name:section_version(xh_s_resource:idc:1.0.1)
instance 是机房 idc 名称
item 是机房的各个资源池剩余资源 (item_name 为资源池标识)
7.2 【青囊】青囊集群级别以及全局级别开关
7.2.1 集群级别开关
namespace:section_name:section_version(qn_c_cluster:group_redis:1.0.1)
instance_name 是各集群唯一标识 id(instance_name 会以字符串方式进行存储)
item 是集群的各个开关及自愈相关的配置信息
7.3 【扁鹊】扁鹊 group/service/unit 级别巡检数据
bianque// 待完善
8 五行 echarts
8.1 访问五行 DB
8.1.1 查询 item 数据
item 行数据需要转换为列数据
例子
8.1.2 行转列参考
举个学生成绩信息的例子
8.1.2.1 建表及插入数据
8.1.2.2 行转列
使用多表连接的方式
使用 MySQL 中 case when then else end 结构
8.1.3 peewee join 例子
You can also order across joins. Assuming you want to order tweets by the username of the author, then by created_date:
SQL
join on
8.2 图表
8.2.1 需求
统计某个 item2=value2, item3=value3 的条件下,item1 的各个 value 的统计数
而图表的下钻可以通过增加 item=value 来进行条件约束
8.2.2 SQL
(1) 直接获取某个 item_name 的 value 分布
(2) condition1
(3) condition1 + condition2
8.3 例子
某个 Redis 机房有断电风险,需要看下此机房可能影响的集群,如果有此机房的主库则需要重点关注下
9 传送门
Facebook 配置中心
OvineData
9.1 其他
Last updated