查看原文
其他

直击京东新一代数据库技术:如何实现极致弹性能力?

2018-01-11 吕信 51CTO技术栈

京东弹性数据库不是一个单一的产品,而是京东在对数据库的使用、运维和开发过程中遇到的一系列问题的解决方案和运维经验的总结升华进而形成的一套产品系列。


京东弹性数据库主要包括三大功能模块:

  • 核心功能模块:JED,提供数据查询和写入的自动路由、自动弹性伸缩、自动 FailOver、自动负载调度和数据库服务智能自治的功能。

  • 实时数据发布与订阅模块: BinLake,完全自助、无状态、自动负载、完全自治、可横向扩展的集群化 Binlog 采集和订阅服务。

  • 自动化运维模块:DBS,实现了京东线上所有数据库服务申请、DDL/DML上线、数据抽取等的流程化和自动化。


今天分为五个部分进行分享:

  • 发展历程

  • 功能特性

  • 整体架构

  • 实现细节

  • 使用情况


发展历程


在 2011 年,我加入京东之初,京东的数据库正处于诸侯混战的阶段,各种数据库都有,包括:MySQL、PostGre、Oracle、SQL Sever。


在 2011 年之后,开始去 IOE,到了 2014 年,京东基本上完成了去 IOE,所有的业务系统都迁移到了 MySQL 上。


在大规模使用 MySQL 的过程中,我们发现,随着业务数据量的增长,很多业务开始了漫长的分库、分表之旅,起初各个业务系统在自己的业务代码中维护分库分表的路由规则。


而且各个业务系统的路由规则和整体设计都不一样,后来由于人员更迭以至于业务代码无法维护,不同业务使用的数据库分库分表模式不尽相同,导致数据库的维护工作也难如登天。


这时我们开始重新思考应该提供什么样的数据库服务,得出了以下几点:

  • 统一分库分表标准

  • 路由针对业务透明

  • 数据库服务伸缩无感知

  • 统一数据服务

  • 业务研发自助申请服务

  • 数据库运维工作自动化


为了实现上述功能特点,我们分为两步走:

  • 优先解决业务和运维窘境,从而争取足够的时间和技术 buffer 进一步完善产品。

  • 最终完美形态的产品研发。


因此,我们首先在 2015 年开发了 JProxy,优先解决紧急的业务和运维难题:分库分表规则统一化和路由透明化。


在拿到充分的时间 buffer 后,我们从 2016 年开始以匠人的精神精雕细琢京东弹性数据库。


功能特性


京东弹性数据库是一个产品系列,主要是解决数据库的运维、使用和研发过程中的问题,具备动态伸缩、高可用、查询透明路由、集群化日志服务和自动化运维等功能,现就京东弹性数据库三个核心模块的功能进行详细说明。


JED(JD Elastic DataBase)


JED 是 JProxy 功能的父集,它除了具备透明路由、统一分库分表标准之外,还提供了五大功能,如下图:

在线动态扩容


起初某个业务可能申请了 4 个分库,后面随着业务的发展,数据量越来越大,可能需要扩容到 8 个分库。


一般的数据库中间件在扩容时,需要与业务研发部门协商一个业务低谷期停业务,然后进行扩容,扩容完毕后重新启动业务。


为了解决这个问题,JED 提供了在线动态扩容功能,扩容只会对业务造成秒级影响,且无需人工介入。


我们现在可以触发自动扩容,设置的策略是当磁盘的使用率达到80%,就自动进行扩容。


自动 FailOver


Master 一旦出现宕机,哨兵检测系统就会第一时间检测到,会自动触发注册在哨兵检测系统中的 Hook 程序。


Hook 程序就会选择一个最新的 Slave 替换 Master,然后更新 ETCD 中的元数据信息,业务方的下一次请求就会发送到新的 Master 上。


兼容 MySQL 协议


JED 是完全兼容 MySQL 协议的,即通过 MySQL 的 Client 端或者标准的 JDBC Driver 都可以连接到 JED 的 Gate 层,然后进行查询和计算。


多源数据迁移


我们基于 ghost 进行改造,开发了京东的数据传输和接入工具: JTransfer,实现了业务数据的动态迁移。


如果以前你的业务是运行在 MySQL 上的,现在要迁到 JED 上,你不需要停止任何业务,直接启动 JTransfer 的数据迁移服务,就可以在后台自动完成数据的同步和迁移。


迁移完毕后,JTransfer 会自行比对 JED 上的数据与原来数据的一致性和 lag 计算。


当数据完全一致, 且 lag 小于 5 秒时,就会邮件通知业务方进行复验,复验没有问题,业务方直接将数据库连接指向到 JED 就可以正常提供服务了。


数据库审计


JED 具有数据库审计的功能,该功能实现在 Gate 层,在 Gate 层我们会得到应用发送给 JED 的所有 SQL,然后将 SQL 语句或者 SQL 模板发送给 MQ。


由于是在 Gate 层实现的,而 Gate 层与 MySQL 服务不在一个容器上,因此对 MySQL 服务不会产生任何的负面影响。


BinLake


BinLake 只做一样工作:集群化 Binlog 的采集和订阅服务。


在 BinLake 之前,我们使用 Canal 进行 Binlog 采集,但我们发现存在资源浪费等问题:若一个业务需要采集 MySQL Binlog,并且还需要 HA 保证的话,我们至少需要两台服务器。


那多个业务怎么办?于是我们开发了 BinLake,其功能特性如下:

无状态集群化 BinLog 采集


BinLake 是一个集群化的 BinLog 采集和订阅服务,并且与常规意义上的集群不一样,我们的集群是没有 Master 节点的。


而且集群中的所有工作节点都是完全平等的,这也就意味着,只要集群中的节点没有全部宕机,BinLake 集群可以一直提供服务。


高可用与自动故障转移


针对于某个 Mya 实例的采集 instance(每个 instance 代表一个线程)一旦挂掉,会在集群中的负载最低的工作节点上重新启动一个 instance,继续从上次挂掉的 Offset 进行采集,不会造成 BinLog 的丢失和重复。


负载自动均衡


假设所有 BinLog 的集群有八个节点,其中有七个节点的负载比较高。


当你在接入 BinLog 时,在没有人工介入的衡量下,整个集群将以新接入的一个 instance 采集实例,自动选择一个健康度最高的 Wave 服务,然后启动 BinLog 采集。


支持多种 MQ


BinLake 采集到的所有 Binlog 的 event 会被封装成 Message 发送给 MQ,目前我们支持 JMQ 和 Kafka 两种 MQ 产品。


支持集群横向扩容


当 BinLake 集群的服务能力达到了瓶颈,我们可以简单地将新的工作节点启动,只需要在新的工作节点配置文件中配置上与线上的工作节点相同的 ZooKeeper 路径,新的工作节点就会自动加入到已存在的 BinLake 集群中。


DBS


DBS 主要完成自动化运维的工作。它可以完成数据库服务的自动化交付、数据库操作的流程化管理、数据库健康指数全面监控、数据库自动备份及结转,以及调度作业的多样化调度(包括定时、依赖以及触发三种调度模式)。

整体架构


如上图是京东数据库的一个整体架构图,最底层是 JDOS2.0,JDOS 2.0 是京东新一代的容器技术,是 Docker 的管理平台。


实际上京东所有的数据库服务现在已经完全运行在 Docker 之上了,这一点是让我们比较引以为豪的工作成绩,而这些都离不开京东 JDOS 的底层支持。


JED 包括六大组件:

  • JED-Gate:实现分库分表的透明化路由和审计功能。

  • JED-Ctl:命令行控制工具。

  • JED-Ctld:也提供集群控制功能,但是它是以服务的方式提供 API 接口。

  • Topology:是整个 JED 的元数据管理中心,所有的元数据是通过 Topology 进行管理的。

  • JED –Tablet:是每一个 MySQL 前端的 Proxy,提供 MySQL 查询缓存和流复制等。

  • JTransfer:在线数据迁移和接入工具。


BinLake 的服务角色比较简单,只有两种服务:Wave 和 Tower。


BinLake 整个集群是完全无状态的。我们所知道的大部分集群化服务都是有状态集群和不对等集群。


所谓不对等集群就是集群里要有 Master 服务角色,负责整个集群的管理;还要有 Worker 服务角色,负责实际任务的执行。


但整个 BinLake 是没有任何 Master 的,只有一种服务角色:Wave,就是你的工作节点。Tower 只是一个可以与集群进行交互式操作的 HTTP 服务。


Tower 与传统 Master 节点的不同之处在于:它不负责任何元数据的管理,它只是向 Topology 服务发送命令,更新或者获取存储在 ETCD 或 ZooKeeper 中的元数据信息。


DBS 是构建于我们的 API Platform 之上的,API Platform 是我们自己开发的一个简单 Faas 平台。


有了 API Platform,在京东只要是会写代码的人,不管你用何种开发语言,只要是满足 Restful 协议的服务,都可以注册到 API Platform 中,并不断丰富 DBS。 


DBS 包括几个核心模块:

  • JGurd 是一个分布式检测系统,它提供了对 MySQL 服务的完全分布式检测,避免了因为网络抖动而产生对 MySQL 健康状况的误判。

  • Scheduler 是调度平台,是基于 Oozie 改造开发的集群调度平台。

  • JProcess Maker 是 DBS 的流程引擎。

  • DBS-Tools 是我们在数据库运维过程中需要用到的一些数据库工具,比如说 AWS 报告、监控工具、Master 切换工具、域名漂移工具等。

  • Authentication 是京东内部的身份认证和权限控制组件。


下面我们针对 JED、BinLake 和 DBS 的架构进行详细讲解。


JED


JED 的前端是 AppServer,从整体架构上,JED 和 AppServer 直接打交道的只有一个角色,就是 JED-Gate。


JED-Gate 完全兼容 MySQL 协议,AppServer 可以将一些查询语句发送给 JED-Gate。


JED-Gate 层对所有查询的查询执行计划都会做缓存,并且根据查询执行计划,通过 Topology 服务获得查询所涉及表的路由源数据信息,根据元数据信息将查询语句改写或者拆分发送到底层的 Shard 上去。


目前 JED 已经满足了广域分布架构,实现了异地多活。


BinLake


针对上图的 BinLake 架构图,可以看到 BinLake 集群中的每个工作节点叫做 Wave。


每个 Wave 节点上有多个 instance,这个 instance 就是针对于每个 MySQL 实例的 Binlog 采集线程,在同一个 Wave 实例上的多个 instance 实例通过 Epoll 模型实现高效网络监听和通讯。


当用户新采集一个 MySQL 的 Binlog 或者某个 instance 线程挂掉了,会根据当前集群中各个 Wave 服务的健康状况选择一个健康度最高的 Wave 实例,去实例化这个新的 instance 线程。


而每个 Wave 实例上的健康度是根据 Zabbix 的监控数据进行动态计算的。


从图中可以看到,Tower 服务其实没有跟 Wave 服务做任何直接的通讯或者联系。


Tower 只会跟 ZK 或 ETCD 集群直接做交互,它对 ZK 或者 ETCD 集群任何元数据的更改都被 Wave 服务及时发现,发现之后,Wave 服务会采取一系列相应的措施,来对元数据的更改进行响应。


DBS


DBS 依赖于两个基础的服务进行构建,第一个是 API Platform,第二个是 JDOS。


通过 API Platform 实现 DBS 整个系统所有功能模块的完全解耦,因为所有的底层操作都是单独开发的符合 Restful 标准的 HTTP 服务,并通过 API Platform 暴露出来。


不管是研发人员还是 DBA,无论使用什么样的开发语言,只要能够开发出符合 Restful 的 HTTP 服务,就可以将其注册到 API Platform 上,并实现 DBS 系统中特定的功能。


无论是 JGuard、JProcessMaker、DBS-Tools 还是 Scheduler,它们做的所有工作都只有一样:调用 API Platform 上所暴露的接口。


API Platform 会根据你的注册信息,去调用 Tower 暴露的 API 接口,或者是调用 MHA 的一些脚本或者其他接口。


另外,不管是 DBS 的应用服务器、MySQL 服务器、API Platform,后端写的所有接口,我们都会采集这些服务上的所有日志,采集了之后接入到 Unilog Platform,用于后续的日志的审计和检查。


实现细节


由于京东弹性数据库包含的功能和组件很多,下面我选出几个特定的功能,在实现细节上详细说明。


动态在线扩容


Step 1:创建两个目标 Shard


假设某个业务方在 JED 中起初申请了一个 Shard,这个 Shard 大家可以把它简单地想象成是一套 MySQL 集群,这时我要将它扩容成两个 Shard。


假设现在有一万条记录,要扩成两个 Shard,那么每个目标 Shard 里面就有 5000 条。


在 JED 里,在触发扩容这个动作时,首先会通过 JDOS 接口,将目标 Shard 的所有 POD 都创建并启动起来。


如果每个目标 Shard 都是 1 主 2 从,总共会启动 6 个POD,12 个 Container(一个 POD 中有 2 个 Container,1 个 Container 中是 Tablet 服务,1 个 Container 是 MySQL 服务)。


然后每个 POD 都是 Not Sevring 状态,其中每三个 POD 实例组成一个 Target shard。


可以看到,Source Shard 中的 sharding key 对应的 key range 是:0x00-OxFF,这里的 KeyRange 也就是你的 sharding key 经过哈希之后能够落到多大的范围。


现在要将一个 Source Shard 分为两个 Target Shard,所以 Source Target 对应的 Key Range 也就要一分为二。


可以看到两个 Target Shard 对应的 KeyRange 是 0x00-Ox80,Ox80-Oxff,并且是 Not Serving 状态。


Step 2:全量数据过滤克隆


两个 Target Shard 建立之后,会根据 ETCD 里的默认配置针对每个 Target Shard 建立 MySQL 的复制关系,比如:

  • 一主两从:一个 Master,一个 Replication,一个 ReadOnly。

  • 一主三从,一个 Master,两个 Replication,一个 Readonly。

  • 一主四从,一个 Master,两个 Replication 和两个 ReadOnly。


建立完复制关系之后,首先会通过 JED-Worker 将 Source Shard 中的 Schema 信息复制到两个 TargetShard 中。


然后将 Source Shard 中的 ReadOnly Pod 从 MySQL 复制关系中摘除下来。


最后通过 JED-Worker 将 ReadOnly 中的数据过滤拷贝到两个 TargetShard 中。


Step 3:增量数据过滤到两个目标 Shard


现在我们以最简单的一拖二的方式来讲述。当你的两个 TargetShard 建立完成后,你要做的就是先把你的这一万行记录拷到两个 shard 上,拷完之后去建立过滤复制。


完成了 Step2 的过滤拷贝之后,将 ReadOnly 重新挂到 Source Shard 上。


然后 JED-Worker 通过 Replication 中的接口创建 Binlog 的过滤复制,会在 Replication 上启动两个协程,并根据 TargetShard 的 KeyRange 分别将 Binlog 复制到对应的 TargetShard 上。


Step 4:数据一致性校验


当 TargetShard 中的 Binglog 与 SourceShard 中的 Binlog 的 lag 小于 5 秒的时候,会启动数据的一致性校验,该过程是在 JED-Worker 上完成的。


过程很简单,就是通过大量的后台协程 Target 和 Source 上去取出数据一条一条对比,如果数据的一致性校验通过,就开始进行 Shard 切换。


Step 5:切 Shard


首先将 SourceShard 中 Slave 的 Serving 状态切换成 Not Serving,同时将 TargetShard 中 Slave 的 Not Serving 状态更改为 Serving。


最后将 Source 中的 Master 停写,等 Target 中的 Master 与 Source 中的 Master 无复制延时后,将 Source Master 停写,通过 JED-Worker 将过滤复制断掉,然后将 Target 的 Master 置为 Serving 状态,并接受写入。


上述的所有 Serving 与 Not Serving 状态的改变均是通过改变 ETCD 中的元数据来完成的。


当前端性业务再发送新的查询过来时,Gate 就会根据最新的元数据信息,将你的这条 SQL 发送到最新的 TargetShard。


自动 FailOver


以 1 主 3 从的 MySQL 主从架构对 JED 的自动 FailOver 机制进行说明。


如果 Master 发生异常,JGuard 会通过分布式检测(JGuard 是通过 ORC 改造之后形成的一个分支检测服务)检测异常。


检测到异常之后会通过邮件和短信通知业务接口人,通知完之后,不会等业务接口人进行处理,直接从当前整个 MySQL 集群当中选择一个 GTID 最大的一个 MySQL 实例,将这个 MySQL 实例切成 Master。


然后根据新的 Master 重建新 MySQL 主从复制关系,将剩余的 Replication 和 ReadOnly 重新挂载到新的 Master 上,再调用 JED-Ctrld 服务的接口更新 ETCD 中的元数据。


这样后续的 DDL/DML 就会发到最新的 Master 之上,最后缺失的一个 Tablet 需要人工补入。


Streaming Process


JED 实现了查询的流式处理,以查询语句 select table_a.age from table_a order by table_a.age 为例说明流式处理的过程。


JED-Gate 接收到该查询语句之后,会根据 ETCD 中的分片元数据,将该语句分发到三个 Shard 中,各个 Shard 返回给 JED-Gate 数据本身就是有序的。


在 JED-Gate 中针对每个 Shard 都会有一个 buffer 与之对应,每个 buffer 用来流式的接收每个 Shard 返回的排序完毕的数据,因此该 buffer 中的数据也是有序的。


然后将每个 buffer 的首地址存储到一个 PriorityQueue 里面, PriorityQueue 是一个堆排序的优先级队列,会根据每个 buffer 中的首元素不断的进行排序。


每从 PriorityQueue 中取出一个元素,PriorityQueue 都会调整 buffer 的先后顺序,JED-Gate 会将元数一个一个地取出来,以流式的方式发给前端,从而实现整体流式排序。


Join 处理


现在我们看下如何在 JED 上执行 Join 查询的,在下面所有的说明中,我们都有一个假设条件,就是所有的表的 sharding key 都是 ID。


对 Join 查询的处理,要分情况:

第一种情况:Join Key 与 Sharding Key 相同。


这种情况下由于 Join Key 和 Sharding  Key 是完全相同的,因此是可以将 Join 查询语句直接发送到下面的每个 shard,在 JED-Gate 汇聚各个 shard 的部分查询结果,并返回给前端应用。

第二种情况:Join Key 与 Sharding Key 相同。


如上图所示,比如 Select a.col,b.col.from a join b on b.id_2=a.id where a.id=0。


针对该查询语句,JED-Gate 首先对其进行 SQL 语句改写,改写为两条语句:

  • select a.col,a.id from a where a.id=0

  • select b.col from b where b.id_2=a.id


在第二个查询语句中的 a.id 是绑定变量。JED-Gate 会首先根据 select a.col,a.id from a where a.id=0,定位到该 SQL 需要定位到哪个 shard,将 SQL 发送到相应的 Shard 执行,并流式的获取其结果。


然后将结果中的 a.id 字段的值取出,并将值赋给 select b.col from b where b.id_2=a.id 语句中的绑定变量 a.id,将复制后的第二条 SQL 语句依次发送给所有的 shard,并将结果与第一条 SQL 语句中的结果组合,流式地返回给前端。

当多级 Join 的时候,也是相同的思路,这里不再赘述。


BinLake 元数据架构图


前面已经提到 BinLake 有一个很大的特点:一个完全无状态的集群,没有 Master 管理节点,而要实现这个特性最重要的就是要有合理的元数据设计。


之所以没有 Master 节点,是因为把 Master 节点的功能委托给了 ZooKeeper 或 ETCD。


通过借助 ZooKeeper 中的 ephemeral znode 实现了 Wave 服务乃至 instance 的自动发现和 HA,并最终实现了无 Master,无状态的完全对等集群。

根据上面的元数据架构我们对 BinLake 的所有元数据进行详细说明。


一个 BinLake 集群的 root znode 是一个名为 wave 的 znode,在 wave 之下是一系列的形式为:MySQL 域名命名:port 的 znode。


这样的每个 znode 都对应了一个 MySQL 实例,而在每个 MySQL 实例对应的 znode 下面是该 MySQL 实例的管理、信息保存和选举 znode。


其中 counter 节点中记录了当前 MySQL 实例对应的 instanc 重启了几次,若连续重启超过 7 次,就会发出报警信息。


而 dynamic 节点则记录了每个 MySQL 实例对应的 Binlog 采集线程对应的快照信息包括:当前采集到的 Binlog 文件、Offset、Timestamp、GTID、最近的 10 个时间点 Binglog 位置和 Filter Rules 等。


从而保证 instance 重启后,可以利用这些信息继续进行 Binlog 采集。


后面的 sequencenumber 对应的一系列 znode 是由 Curator 自动创建的 znode,来保证选举的正确性和防止羊群效应。


而“Bingdleader:wavehost”对应的 znode,主要用于人工介入 binlake,从而指定让下次 instance leader 选举的时候,固定在 wavehost 对应的 Wave 节点上。


如果我某个 MySQL 采集的 instance 挂了,Curator 就会在后面的第一个 znode 对应的 wave 服务上首先进行 leader 选举。


若成功选举,就接入,否则依次对后面对应的每个 Wave 实例进行选举,直到成功选举出 leader。


选举出新的 leader 之后,就会在对应的 Wave 服务上重启 Binlog 采集的 instance 线程,该 instance 就会根据 dynamic znode 中存储的快照信息重建 MySQL 的复制关系,继续进行 Binlog 采集。


集群化 Binlog 订阅


BinLake 中的 Binlog 采集方式有两种:

  • 时序

  • 乱序


时序:通过 NIO 实现的类似 Epoll 的网络模型监听所有与 MySQL 之间的链接的网络事件等,检测到与某个 MySQL 之间的连接有 byte 流到达时,就会尽量多的读取所有的 byte 流。


将其全部放到一个 Byte Buffer 里,然后通过 Worker Thread 对 ByteBuffer 中的 Byte 进行 Decode,并解析成一个个的 EventMsg,进而将 EventMsg 也放到一个 MessageBuffer 中。


在 MessageBuffer 后面有一个 Handler 线程,这个 Handler 线程会根据 ZooKeeper 里的一些元数据信息(比如:Topics、FilterRules、MQ 类型和地址等)对 EventMessage 进行处理。


然后使用 protobuff 进行序列化后发送到正确 MQ 中的特定的 Topic 里。这里的处理包括:根据库表类型过滤、列过滤、事务头 Event 和尾 Event 过滤等。


乱序:从上图中可以看出乱序处理与时序处理的前半部分是相同的,只是在 EventMessage Buffer 后面是通过线程池进行并发处理的,测试结果表明乱序处理的性能是时序处理性能的 10 倍。


落地使用


从上图可以看出,JED 数据库中间件服务通过 JTransfer 来实现 MySQL 和 JED 之间的数据正反向同步和传输。


现在 JED 可以实现 MySQL 向 Oracle、Postgre 等多种数据库的实时数据同步和传输。


BinLake 可以对 MySQL 和 JED 中的 Binlog 进行采集,并发送到 JMQ 或者 Kafka。


在 MQ 后端有两种使用方式:

  • 通过 Spark Streaming 把它同步到 HBase 里,目前京东内部实际上是有一个项目叫做实时数据快照,就是通过这种方式,实现了 HBase 中的数据与线上 MySQL 实例中的数据的完全实时同步更新。

  • 下游各个业务部门各自通过 Consumer 消费,进而进行订单积压监控、智能报表以及营销实时推荐等。当然 JED 以及 BinLake、Jtransfer 都是通过 DBS 进行自动化运维、调度和管理的。


京东弹性数据库落地状况


这些是在 9 月份从 DBS 系统里面拿到的数据,服务线上业务是指上线项目的个数。


目前京东弹性数据库服务了线上 3122 个项目,管理的 MySQL 实例个数有将近两万个,管理的 Table 就比较多了,有 660 多万个,并且完成了自动在线切换 2700 余次,自动化上线有 27000 余次。


现在京东有一般的业务都迁到了 JED 上,当然还有一半的业务正在容器化的 MySQL 服务上并逐步地进行迁移。


分片数与 OPS、延时的关系情况



上图是 JED 的分片数与 OPS 以及分片数延时的一些关系。从图中可以看出,随着分片数的增加 JED 的服务能力也出现线性增长的趋势。而随着分片数的增加延时几乎没有变化(延时的单位是毫秒)。


Gate 数与 OPS、延时的关系情况



上图是 Gate 数目与 OPS 以及 Gate 数目与延时的关系。从图中可以看出,通过简单的增加 Gate 的数目而实现 JED 数据库服务能力的横向扩展,不会导致明显的延时增加。

微信后台回复关键词“京东”,即可下载完整版PPT资料

作者:吕信

编辑:陶家龙、孙淑娟

出处:转载自DBAplus社群微信公众号,本文根据吕信老师在〖Gdevops 2017全球敏捷运维峰会广州站〗现场演讲内容整理而成。


吕信,京东商城数据库技术部资深架构师,拥有多年数据产品研发及架构经验。在京东及国内主导多种数据产品开发及社区建设,积极活跃于数据产品领域,对数据库及大数据领域各个产品具有丰富经验,目前在京东商城主导弹性数据库研发及推广使用。

精彩文章推荐:

如何构建万台服务器下的立体化监控体系?

阿里万亿交易量级下的秒级监控

大白话理解“最晦涩”的Paxos算法及在数据库高可用上的使用

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存