数据服务之最佳实践

性能
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

  • 修改问题资源的元数据为失效,重新加载资源后访问请求会失效