数据服务之最佳实践
性能
1)资源分配:
① 剥离计算资源:对于复杂逻辑的计算,每次调用查询接口计算成本高,所以对于复杂逻辑将其全部交由底层数据公共层处理,而只保留核心业务逻辑
② 查询资源分配:根据查询结果的数量你把查询分为get/list两种,get返回一条结果,基本都转化为KV查询,效率极高;list返回多条数据,代价高一些。如果把get/list查询都放在一个线程池中,get请求会等待list请求,而降低QPS(每秒查询数量),所以普遍把两种请求放在不同线程池
③ 查询优化:调用者为了简单往往不会清楚区分get与list查询,而都用list方法,因此需要按照sql中的筛选字段和筛选条件进行判断
2)缓存优化
① 元数据缓存:查询时需要使用元数据的逻辑表与物理表的映射关系;sql安全检查需要用到表配置信息;字段权限检查需要用到权限元数据,同时元数据的总量不大,保存一份在内存中可以提升效率
② 查询模型缓存:一个完整的请求处理过程如下,可以将DSL解析后的逻辑模型、物理模型进行缓存,当再次遇到类似的SQL可以提升效率省去虚线部分
具体流程如下:
-
解析DSL,语法、词法分析将where中的常量替换,如where id=123替换为where id=?
-
用替换后的语句做key,在本地缓存中查找
③ 结果缓存:对于执行耗时的查询进行结果缓存;对不易变的查询结果进行缓存
3)查询能力:对于追求数据实时性的查询,用推送的方式代替轮询可以减轻服务器压力,对于推送消息有如下优化:
① 过滤后的消息放入消息队列,采用无锁队列性能优于锁队列
② 消息推送基于socket,采用异步事件驱动的网络通信框架netty
③ 推送是典型的io密集型系统,采用协程(内部可中断的子程序)减少线程的上下文切换
④ 批量推送消息
稳定性
1)发布系统:用户在修改了元数据后,新发布服务,如何保证变更的安全性
① 元数据隔离:应用分三级,分别对应三个元数据系统
-
日常环境:用于线下开发测试
-
预发环境:用于正式发布前的校验
-
线上环境:用于正式发布环境
修改元数据后的发布进入欲发布环境,在其中测试安全性,是有影响其他功能,通过测试后正式上线。同时有一个定时任务定期将预发元数据同步到日常环境
② 隔离发布:不同用户发布的服务不会互相影响
-
数据资源划分:查询操作最终会落在逻辑表上的操作,所以把隔离的力度控制在逻辑表
-
资源独占:用户修改时,锁住所用逻辑表及其下所有物理表,当变更完成发布后才会释放资源
-
增量更新:用户修改完逻辑表后,发布时不需要重新加载全量数据而是只加载所发布的逻辑表元数据
2)隔离:将系统划分成多个模块,当某个模块出现故障,不影响整体系统的运行;对资源进行有效管理
① 机房隔离:双机房容灾,前提时保障服务调用同机房优先,最大程度减少双机房的网络开销
② 分组隔离:调用者分层,资源分组;每一个分组有明确的服务对象,己试某些组出现性能较差的情况也不会影响其他分组
3)安全限制:防止用户做太消耗资源的查询
① 查询强制加上limit
② 配置查询必须传入的字段,防止*做全表查询
4)监控:
① 调用日志采集:采集点如下
② 调用监控:监控点如下
5)限流、降级:流量突然增大时,对系统的保护措施
① 限流:对调用者、查询表分别做了QPS限制, 超过阈值的流量会被过滤掉
② 降级:
-
QPS设置为0
-
修改问题资源的元数据为失效,重新加载资源后访问请求会失效