QCon北京开幕在即|与全球 140+ 顶尖工程师共同解构 AI 时代的技术浪潮 了解详情
写点什么

Oracle 专家谈 MySQL Cluster 如何支持 200M 的 QPS

  • 2015-07-02
  • 本文字数:2995 字

    阅读完需:约 10 分钟

Andrew Morgan 是 Oracle MySQL 首席产品经理。 近日,他撰文介绍了MySQL Cluster 如何支持200M 的QPS。

MySQL Cluster 简介

MySQL Cluster 是一个实时可扩展且符合 ACID 的事务型内存数据库。该数据库有高达 99.999% 的可用性和低廉的开源软件总拥有成本。在设计方面,它采用了一种分布式、多主节点的架构,消除了单点故障,能够在商用硬件上横向扩展,并借助“自动分片(auto-sharding)”功能为通过 SQL 和 NoSQL 接口访问数据的读 / 写密集型工作负载提供服务。

最初,MySQL Cluster 被设计成一个嵌入式的电信数据库,用于网内应用程序,需要具备运营商级的可用性和实时性能。之后,其功能随着新功能集的增加迅速增强,其应用领域随之也扩展到了本地或云上的 Web、移动和企业应用程序,包括:大规模 OLTP、实时分析、电子商务(库存管理、购物车、支付处理、订单追踪)、在线游戏、金融交易(欺诈检测)、移动与微支付、会话管理 & 缓存、流式推送、分析及推荐、内容管理与交付、通信与在线感知服务、订阅者 / 用户信息管理与权益等。

MySQL Cluster 体系结构

在 MySQL Cluster 内部,总共有三种类型的节点为应用程序提供服务。下面是一张 MySQL Cluster 体系结构简图,其中包含 6 个节点组,共 12 个“数据节点(Data Node)”:

数据节点是 MySQL Cluster 的主要节点。它们提供如下功能:内存内及基于磁盘的数据存储与管理、表的自动“分片(sharding)”及按用户定义分区、数据节点间数据同步复制、事务与数据检索、自动故障恢复、自我修复(故障解决后自动重新同步)。

表会自动跨数据节点分区,每个数据节点都是一个可以接受写操作的主节点。这使得写密集型工作负载很容易在节点之间分配,而且对于应用程序而言,这个过程是透明的。

MySQL Cluster 采用了一种无资源共享的体系结构(比如不使用共享磁盘)存储和分发数据,并同步生成至少一个数据副本,如果某个数据节点出现故障,则总是有另一个数据节点存储了同样的信息, 使得请求和事务可以继续而不被中断。任何在数据节点故障期间短暂中断(亚秒级)的事务都可以回滚并重新执行。

MySQL Cluster 允许用户选择如何存储数据:全部在内存中或者部分在磁盘上(仅限于未索引数据)。内存内存储对于经常变化的数据(活动工作集)而言尤其有用。存储在内存中的数据会定期地(本地检查点)写入本地磁盘,并在所有数据节点之间协调,这样,MySQL Cluster 可以从系统完全失效(比如停电)的情况下恢复过来。基于磁盘的存储可以用于存储性能要求不那么严格的数据,其数据集大于可用内存。与其它大多数数据库服务器一样,为了提高性能,MySQL Cluster 使用页缓存将经常使用的、基于磁盘存储的数据缓存在数据节点的内存中。

应用节点提供从应用逻辑到数据节点的连接。应用程序可以使用 SQL 访问数据库,通过一台或多个 MySQL 服务器对存储在 MySQL Cluster 中的数据执行 SQL 接口的功能。当访问 MySQL 服务器时,可以使用任何一种标准的 MySQL 连接器,这使用户有许多种访问技术可选择。NDB API 是其中一个可选的方案。这是一个基于 C++ 的高性能接口,可以提供额外控制、更好的实时行为及更高的吞吐能力。NDB API 还提供了一个层,使 NoSQL 接口可以绕过 SQL 层直接访问 MySQL Cluster,降低了延迟,提高了开发灵活性。现有接口包括 Java、JPA、Memcached、JavaScript 与 Node.js、HTTP/REST(借助 Apache Module)。所有应用节点都可以访问所有数据节点的数据,所以,它们即使出现故障也不会导致服务中断,因为应用程序只要使用剩下的节点就可以了。

管理节点负责向 MySQL Cluster 中的所有节点发布集群配置信息以及节点管理。管理节点在启动、向集群加入节点及系统重新配置时使用。管理节点关闭和重启不会影响数据节点和应用节点的运行。在默认情况下,在遇到导致“集群分裂(split-brain)”或网络分区的网络故障时,管理节点还提供仲裁服务。

通过透明分片实现可扩展性

任何表的行都可以透明地分成多个分区/ 片段。对于每一个片段,都会有一个单独的数据节点保存它所有的数据,并处理所有针对那些数据的读写操作。每个数据节点还有一个伙伴节点,它们共同组成了一个节点组;伙伴节点存储了那个片段的第二个副本以及一个它自己原有的片段。MySQL Cluster 使用同步两段提交协议确保事务提交的变化同时存储到两个数据节点。

MySQL Cluster 默认使用表的主键作为“分片键(shard key)”,并对分片键执行 MD5 散列,从而选择数据应该存储的片段 / 分区。如果一个事务或查询需要访问多个数据节点的数据,那么其中一个数据节点将承担事务协调器的角色,并将工作委派给其它所需的数据节点;结果会在提供给应用程序前合并。需要注意的是,事务或查询可以连接来自多个分片和多个表的数据,这与传统的、实现了分片机制的 NoSQL 数据存储相比是一个巨大的优势。

当单个节点就可以满足高强度查询 / 事务的数据操作需求时,就实现了最理想的(线性)扩展(因为这减少了数据节点间消息传递的网络延迟)。要做到这一点,应用程序应该清楚地知道数据分布——这实际上就是说定义模式的人可以指定用作分片键的列。比如,上图中的表使用了由 user-id 和服务名组合而成的主键;如果只使用 user-id 作为分片键,那么表中特定用户的所有行将会总是存储在同一个片段中。更为强大之处在于,如果其它表中也使用了同样的 user-id 列,并将其设定为分片键,那么所有表中特定用户的数据都会存储在同一个片段中,那个用户的查询 / 事务就可以由单个数据节点处理。

利用 NoSQL API 最大限度地提高数据访问速度

MySQL Cluster 提供了许多种数据访问方式;最常用的方法是 SQL,但从下图可以看出,还有许多原生 API 可供应用程序从数据库直接读 / 写数据,避免了向 SQL 转换并传递给 MySQL 服务器的低效和开发复杂度。目前,MySQL Cluster 提供了面向 C++、Java、JPA、JavaScript/Node.js、HTTP 及 Memcached 协议的 API。

基准测试:每秒 2 亿次查询

根据设计,MySQL Cluster 用于处理以下两种工作负载:

  • OLTP(在线事务处理):内存优化型表可以提供次毫秒级的低延迟以及极高水平的 OLTP 工作负载并发能力,并且仍然可以提供良好的稳定性;此外,它们也能够用于基于磁盘存储的表。
  • 即时搜索:MySQL Cluster 提高了执行表扫描时可以使用的并发数,极大地提高了未索引列的搜索速度。

话虽如此,MySQL Cluster 旨在处理 OLTP 工作负载方面达到最佳,特别是在以并发方式发送大量查询 / 事务请求的情况下。为此,他们使用 flexAsynch 基准测试,测量更多数据节点加入集群后 NoSQL 访问性能的提升。

在该基准测试中,每个数据节点运行在一个专用的 56 线程 Intel E5-2697 v3(Haswell)机器上。上图显示了在数据节点从 2 增加到 32(注意:MySQL Cluster 目前最多支持 48 个数据节点)的过程中吞吐量的变化。从中可以看出,吞吐量呈线性增长,在 32 个数据节点时,达到了每秒 2 亿次 NoSQL 查询

读者可以登录 MySQL Cluster 基准测试页面,查看关于这次测试的最新结果及更详细的描述。

每秒 2 亿次查询的基准测试是在 MySQL Cluster 7.4(最新的正式版本)上得出的,关于该版本的更多信息请查看这里


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-07-02 00:216741
用户头像

发布了 1008 篇内容, 共 409.2 次阅读, 收获喜欢 346 次。

关注

评论

发布
暂无评论
发现更多内容

如果你想写自己的Benchmark框架

程序那些事

JVM 性能调优 GC benchmark

使用 Dockerfile 创建镜像 | Docker 系列

AlwaysBeta

Docker 容器 镜像 Dockerfile

图说前端-ArrayBuffers 和 SharedArrayBuffers(2/3)

梦见君笑

大前端 内存管理

ARTS 打卡 第2周

Scotty

《精益思想》读后感分享

zhongzhq

高效工作 精益 精益思想 精益生产方式

游戏夜读 | 如何分析游戏体验?

game1night

RESTful 架构及实践

Geek_z9ygea

Java 大前端 RESTf

猿灯塔:spring Boot Starter开发及源码刨析(三)

猿灯塔

Java 猿灯塔

基于Kubernetes实现的大数据采集与存储实践总结

岿然独存5

Docker Kubernetes S3 EFK Fluentd

redis里的数据结构

流沙

redis

图解:深度优先搜索与广度优先搜索

淡蓝色

Java 数据结构 算法

无价值人生记录.0:浪费1000%时间去做一个用来节省1%时间的“轮子玩具”(上:因缘)

八苦-瞿昙

C# 程序员 随笔 随笔杂谈 aop

玩转Redis高可用 - 哨兵(Sentinel)模式

Man

高可用 redis高可用 中间件

DOM 树的构建

法正

html 大前端 DOM

如何基于 BitMap 进行海量数据分析

GrowingIO技术专栏

互联网 数据分析 科技互联网 数据化

给 Spring Boot 项目减减肥!18.18M 到 0.18M 是如何做到的?

给你买橘子

Java 程序员 Spring Cloud 编码 SpringBoot 2

图说前端-内存管理(1/3)

梦见君笑

大前端 内存

计算机的时钟(一):NTP协议

ElvinYang

计算机操作系统基础(十七)---进程同步之Unix域套接字

书旅

php laravel 线程 操作系统 进程

架构师必须知道的架构知识

架构 架构师 Architecture Architect

redis系列之——Redis为什么这么快?

诸葛小猿

Java redis 程序员

如何搭建一个HBase集群

Rayjun

HBase

java 后端博客系统文章系统——No3

猿灯塔

Java 线程的生老病死

武培轩

Java 线程 多线程 并发 线程状态

那些让程序员目瞪口呆的Bug

Java小咖秀

程序员 bug

Git 常用操作汇总-cheat sheet

多选参数

git GitHub gitlab gitee

刘华:上云还是不上云,这是一个问题

刘华Kenneth

架构 敏捷

啃碎并发(九):内存模型之基础概述

猿灯塔

Java 猿灯塔

图说前端-使用Atomics避免SharedArrayBuffers中的race conditions(3/3)

梦见君笑

大前端 内存管理

分布式系统的一些基础理论

俊俊哥

分布式事务 CAP Base

架构师训练营第六周作业

张明森

Oracle专家谈MySQL Cluster如何支持200M的QPS_Oracle_谢丽_InfoQ精选文章