课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
数据库的搭建与使用能够让企业更快的获取到所需的内容。今天,我们就一起来了解一下,在数据库访问以及优化方面我们都需要注意哪些要点。
数据访问中间件是独立部署的数据库的透明代理,本身需要是以集群方式支持高可用,背后还需要对接多套数据库作为一个集群,一般而言会提供如下的功能:
常用的功能就是读写分离。也包括负载均衡和故障转移的功能,自动在多个从库做负载均衡,通过可用性探测,在主库出现故障的时候配合数据库的高可用和复制做主库的切换。
随着数据量的增多需要分片功能。分片也就是Sharding,把数据按照一定的维度均匀分散到不同的表,然后把表分布在多个物理数据库中,实现压力的分散。这里写入的Sharding一般而言没有太多的差异,但是读取方面因为涉及到归并汇总的过程,如果要实现复杂功能的话还是比较麻烦的。由于分片的维度往往可能有多个,这方面可以采用多写多个维度的底层表来实现也可以采用维度索引表方式来实现。
其它一些运维方面的功能。比如客户端权限控制,黑白名单,限流,超时熔断,和调用链搭配起来的调用跟踪,全量操作的审计搜索,数据迁移辅助等等。
更高级的话可以实现SQL的优化功能。随时进行SQL的Profiler,然后达到一定阈值后提供索引优化建议。
其它。极少的代理实现了分布式事务的功能(XA)。还可以实现代理层面的分布式悲观锁的功能。其实细想一下,SQL因为并不是直接扔到数据库执行,这里的可能性就太多了,想干啥都可以。
实现上一般需要做下面几件事情:
有一个高性能的网络模型,一般基于高性能的网络框架实现,毕竟Proxy的网络方面的性能不能成为瓶颈。
有一个MySQL协议的解析器,开源实现很多,拿过来直接用即可。
有一个SQL语法的解析器,Sharding以及读写分离免不了需要解析SQL,一般流程为SQL解析、查询优化、SQL路由、SQL重写,在把SQL提交到多台数据库执行后进行结果归并。
Proxy本身好是无状态节点,以集群方式实现高可用。
这些功能除了Proxy方式的实现还有和数据访问标准结合起来的实现,比如改写JDBC的框架方式实现,两种实现方式各有优缺点。框架方式的实现不局限于数据库类型,性能略高,Proxy方式的实现支持任意的语言更透明,功能也可以做的更强大一些。近还出现了边车Sidecard方式实现的理念,类似于ServiceMesh的概念,网上有一些资料,但是这种方式到目前为止还没看到成熟的实现。
分布式缓存中间件
类似于数据库的Proxy,这里是以缓存服务作为后端,提供一些集群化的功能。其实不采用Proxy方式做,开发一个缓存客户端在框架层面做也是完全可以的,但是之前也说了这两种方式各有优劣。代理方式的话更透明,如果有Java、Python、Go都需要链接Redis,我们无需开发多套客户端了。一般实现下面的功能:
分布式。这是基本的,通过各种算法把Key分散到各个节点,提供一定的容量规划和容量报警功能。
高可用。配合Redis的一些高可用方案实现一定程度的高可用。
运维方面的功能。比如客户端权限控制,黑白名单,限流,超时熔断,全量操作的审计搜索,数据迁移辅助等等。
跟踪和问题分析。配合全链路监控实现一体化的缓存访问跟踪。以及更智能的分析使用的情况,结合缓存的命中率,Value的大小,压力平衡性提供一些优化建议和报警,尽早发现问题,缓存的崩盘往往是有前兆的。
完善的管理后台,可以一览集群的用量、性能,以及做容量规划和迁移方案。
如果Redis集群特别大的话的确是有一套的自己的Proxy体系会更方便,小型项目一般用不到。
任务(Job)管理
之前有提到过,Job是我认为的互联网架构体系中三马车的三分之一,扮演了重要的角色。开源实现的管理的实现有两种方式,一种是类似于框架的方式,也就是Job的进程是一直启动着的,由框架在合适的时候调用方法去执行。一种是类似于外部服务的方式,也就是Job的进程是按需要在合适的机器启动的。在本文一开始的图中,我画了一个任务调度的中间件,对于后一种方式的实现,我们需要有一套中间件或独立的服务来复杂Job进程的拉起。整个过程如下:
找一些机器加入集群作为我们的底层服务器资源。
Job编译后打包部署到统一的地方。Job可以是各个语言实现的,这没有关系。可以是裸程序,也可以使用Docker来实现。
在允许Job前我们需要对资源进行分配,估算一下Job大概需要怎么样的资源,然后根据执行频次统一计算得出一个合适的资源分配。
由中间件根据每一个Job的时间配置在合适的时候把进程(或Docker)拉起执行,执行前根据当前的情况计算分配一个合适的机器,完成后释放资源,下一次执行不一定在同一台机器执行。
这样的中间件是更底层的一套服务,一般而言任务框架会提供如下的功能:
分布式。Job不会受限于单机,可以由集群来提供运行支持,可以随着压力的上升进行集群扩容,任何一台机器的宕机不会成为问题。如果我们采用中间件方式的话,这个功能由底层的中间件来支持了。
API层面提供丰富的Job执行方式。比如任务式的Job,拉数据和处理分开的Job。拉数据和处理分开的话,我们可以对数据的处理进行分片执行,实现类似Map-Reduce的效果。
执行依赖。我们可以配置Job的依赖关系实现自动化的Job执行流程分析。业务只管实现拆散的业务Job,Job的编排通过规则由框架分析出来。
整合到全链路监控体系的监控跟踪。
丰富的管理后台,提供统一的执行时间、数据取量配置,提供Job执行状态和依赖分析一览,查看执行历史,运行、暂停、停止Job等等管理功能。
发布管理
发布管理其实和开发没有太大的关联,但是我觉得这也是整个体系闭环中的一个环节。发布管理可以使用Jenkins等开源实现,在后期可能还是需要有自己的发布系统。可以基于Jenkins再包一层,也可以如开始的图所示,直接基于通用的任务调度中间件实现底层的部署。一般而言,发布管理有下面的功能:
丰富的任务类型和插件,支持各种语言程序的构建和发布。有基本的发布、回滚、重启、停止功能。
支持项目的依赖关系设置,实现自动化的依赖路径上的程序自动发布。
一些运维层面的控制。比如和CMDB结合做权限控制,做发布窗口控制。
用于集群的发布流程。比如可以一览集群的分组,设置自动的灰度发布方案。
适合自己公司的发布流程。比如在流程控制上,我们是Dev环境到QA到Stage到Live。其中,QA环境经过QA的确认后可以进入Stage环境,经过开发主管的确认后可以到Stage环境,经过产品经理的确认后可以进入Live环境进行发布。在发布系统上我们可以结合OA做好这个流程的控制。
在构建的时候,集成单元测试,集成编码规范检查等等,在后台可以方便的看到每一次发布的代码变更,测试执行情况以及代码规范违例。
Jenkins等系统在对于1和2做的比较好,对于和公司层面其它系统的结合无能力为,往往处于这个原因我们需要在Jenkins之上包装出来自己的发布系统。
作者:lovecindywang
节选:博客园
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。