mysql kingshard 扩容_如何用Go打造一个高性能mysql proxy

kingshard架构设计和功能实现

kingshard(https://github.com/flike/kingshard)开源有一段时间了,有些热心的用户发邮件来咨询kingshard的设计和实现问题。于是周末抽空写了一篇介绍kingshard架构和功能实现的文章,希望通过本文能够让用户对kingshard有更深的了解。下面分模块来介绍kingshard的核心组件的设计和实现。

1. 整体架构

kingshard采用Go开发,充分地利用了Go语言的并发特性。Go语言在并发方面,做了很好的封装,这大大简化了kingshard的开发工作。kingshard的整体工作流程入下所述:读取配置文件并启动,在配置文件中设置的监听端口监听客户端请求。

收到客户端连接请求后,启动一个goroutine单独处理该请求。

首选进行登录验证,验证过程完全兼容MySQL认证协议,由于用户名和密码在配置文件中已经设置好,所以可以利用该信息验证连接请求是否合法。 当用户名和密码都正确时,转入下面的步骤,否则返回出错信息给客户端。

认证通过后,客户端发送SQL语句。

kingshard对客户端发送过来的SQL语句,进行词法和语义分析,识别出SQL的类型和生成SQL的路由计划。如果有必要还会改写SQL,然后转发到相应的DB。也有可能不做词法和语义分析直接转发到相应的后端DB。如果转发SQL是分表且跨多个DB,则每个DB对应启动一个goroutine发送SQL和接收该DB返回的结果。

接收并合并结果,然后转发给客户端。

kingshard工作整体流程可参考下面这幅图。 687474703a2f2f7777332e73696e61696d672e636e2f6c617267652f3665353730356135677731657632373030307276766a3230716f306b306467682e6a7067 kingshard整体架构图如下所示 687474703a2f2f7777342e73696e61696d672e636e2f6c617267652f3665353730356135677731657632367a68796d6c336a3230716f306b306467722e6a7067

2. 词法和语义分析

要将kingshard的功能做的足够强大,就不得不进行SQL的词法和语义分析。SQL语句的词法分析指的是将SQL语句切分成一个一个的关键字。例如对SQL语句:select name from stu where id < 13进行词法分析,得到的结果是:{"select","name","from","stu","where","id","

数据分片,解析出表名和查询条件,将SQL路由到正确的DB。

SQL黑名单,通过词法和语义分析,也可以快速识别出需要屏蔽的SQL语句。例如,检测到delete语句不带where操作,就可以直接阻断该SQL的转发。

kingshard并没有考虑完全兼容MySQL所有语法,因为完全兼容MySQL语法会使得词法和语义分析模块变得异常复杂,而且低效。对于DDL语句其实没必要解析,只要能正确转发到后端相应的DB上就可以。

kingshard只对部分DML语句(select,update,insert,delete,replace)进行了解析,这样可以满足绝大部分的分表操作。对于其他语句,kingshard会将其发送到一个默认的DB,或者通过kingshard特有的方式将其发送到指定的DB上,例如: /*node2*/insert into stu(id,name) values(12,'xiaoming'),对于这种带有注释的的sql语句,kingshard能够识别出,然后将这条sql语句发送到node2节点的Master DB上。

3. 负载均衡

用户使用Mysql Proxy目的很大一部分就是为了降低单台DB的负载,将读压力分担到多台DB上。kingshard支持多个slave,不同的slave可以配置不同的读权重,权重越大分担的读请求越多。kingshard读请求负载均衡采用的是权重轮询调度算法。

大部分系统采用该算法时,都是转发SQL语句时,动态地计算出本次选取DB的序号。然后将读请求的SQL语句发送到该DB。仔细分析一下,这样做其实是没有必要的。因为DB的权重是相对固定的,不会经常变动,所以完全可以计算出一个固定的轮询序列,然后将这个序列保存在一个数组中。这样不需要动态计算,每次读取数组就可以。举个例子来说,在kingshard的node配置项中配置slave选项: slave:192.168.0.12@2,192.168.0.13@3 kingshard在读取配置信息初始化系统的时候,就生成了一个轮询数组:[0,0,1,1,1]。在kingshard中会将这个数组打乱顺序,变成:[0,1,1,0,1]。这样就避免了动态计算DB下标的问题,对性能提升有一定帮助。

4.sharding实现

首选需要介绍两个概念:子表,在kingshard中一张逻辑上的大表由若干张小的子表组成。例如:将stu表分成stu_0000,stu_0001,stu_0002,stu_0003。 在数据库中stu表是不存在的,它只是一张逻辑上的表。数据库中只存在四张子表(stu_0000,stu_0001,stu_0002,stu_0003)。 发送SQL语句时,kingshard会识别出需要分表的SQL语句,并改写该SQL。例如,客户端发送过来的SQL语句是:select name from stu where id =10; kingshard收到该SQL语句后,从配置信息中识别出该表是一个Hash类型的分表。根据分表规则,将该SQL改写成:select name from stu_2 where id =10; 然后发送给对应的DB。

Node,子表分布在各个node上,每个node包含一个maser server和若干个slave server(slave个数可以为0)。写请求会发往该node中master server,读请求会发往该node中的slave server。

kingshard的sharding采用了两级映射的思想,首选根据SQL语句的分表条件计算出这条SQL语句落在哪个子表上,然后再根据配置信息找到该子表 落在哪个node上。采用两级映射的思想,对于MySQL的扩容和缩容都能很方便地支持。目前kingshard sharding支持insert, delete, select, update和replace语句, 所有这五类操作都支持跨子表。但写操作仅支持单node上的跨子表,select操作则可以跨node,跨子表。

对于有些表没有分表,操作该表的SQL语句会发往default node。或者用户可以选择在SQL语句前面加上注释,指定该SQL要发往的node,kingshard接收到语句后,识别出注释中指定的node,然后将该SQL发往对应node中合适的DB。例如用户发送/*node1*/select * from member where id=100,kingshard接收到该SQL后会将其发送到node1的salve上。这样kingshard就能很好地兼容分表和不分表的各种应用场景了。

5. 事务的实现

所有proxy支持shard后都会面临一个问题:支不支持分布式事务?出于性能和可用性考虑, kingshard只支持单台DB上的事务,不允许跨DB的事务。kingshard处理单DB上的事务流程如下:用户发送begin语句。

kingshard接收到SQL语句后,将该连接的状态设置为事务。

用户发送DML语句,kingshard识别出语句需要发送到的DB,然后kingshard新建一个与后端DB的连接中取一个连接,利用该连接发送语句。

收取SQL语句的结果后,将连接放回。

kingshard收到下一条SQL语句,判断该SQL是不是发往同一个DB,如果不是则报错。如果是发往同一个DB,则利用该连接发送语句。

收到用户发送的commit语句,将该连接的状态设置为非事务,事务结束。

6. 后端DB存活检测

kingshard每个node启动了一个goroutine用于检测后端master和slave的状态。当goroutine持续一段时间(由配置文件中down_after_noalive参数设置)ping不通后端的DB后,会将该DB的状态设置为down,后续kingshard就不会将sql语句发往该DB了。

7. 客户端白名单机制

有时候用户为了安全考虑,希望只能某几台server能够连接kingshard。在kingshard的配置文件中有一个参数:allow_ips,用于实现客户端白名单机制。当管理员设置了该参数,则意味着只有allow_ips指定的IP能够连接kingshard,其他IP都会被kingshard拒绝连接。如果不设置该参数,则连接kingshard的客户端不受限制。

8. 管理端设计和实现

kingshard的管理端口复用了工作端口,通过特定的关键字(admin)来标示。kingshard是通过对管理端特定的SQL进行词法和语义分析,将SQL语句解析为一条kingshard可以识别的命令。目前支持平滑上下线master和slave,和查看kingshard配置和后端DB状态。后续打算将web页面集成到管理端,这样用户就可以不用输入命令行操作,而是在网页上操作。大大降低用户使用kingshard的门槛。

上述各个模块都是kingshard中比较核心的模块,通过这篇文章的介绍,我想读者应该对kingshard的架构和实现有了初步的了解。很多功能的设计和实现,都是作者慢慢地摸索和实践。如果有读者对kingshard的设计或实现感兴趣或者对上述设计有不同的想法,欢迎发邮件(flikecn#126.com)给我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/426171.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩转oracle 11g(27):ora-12154和客户端版本低

16. 64bit windows操作系统上 安装了32bit的oracle alert log 里不断的出现如下错误&#xff1a; OER 7451 in Load Indicator : Error Code OSD-04500: illegal option specified O/S-Error: (OS 1) 函数不正确。! 每10秒出现一次错误提示。 解决方案&#xff1a; 重新安装or…

mysql 命令行 主从复制_MySQL 的主从复制(高级篇)

首先要明白为什么要用 mysql 的主从复制&#xff1a;1–在从服务器可以执行查询工作 (即我们常说的读功能)&#xff0c;降低主服务器压力&#xff1b;(主库写&#xff0c;从库读&#xff0c;降压)2–在从主服务器进行备份&#xff0c;避免备份期间影响主服务器服务&#xff1b;…

[Android]安装 Android Studio 第一行Android代码

安装 Android Studio 1.下载 官网 建议官网下载https://developer.android.com/index.html 网盘 链接&#xff1a;https://pan.baidu.com/s/1b8KyEMYbSYt9EQJ2e8Ge6w 提取码&#xff1a;ytn4 《第一行代码》第二版提供版本&#xff08;2016年&#xff09; 2.安装组件全…

玩转oracle 11g(28):ora-00064和程序异常终止

18.ORA-00064 object is too large to allocate on this OS 问题原因&#xff1a; 通过查看告警日志&#xff0c;确认修改的process过大 解决步骤&#xff1a; 使用 D:\oracle\product\10.2.0\admin\docare\pfile\init.ora 启动 操作步骤如下&#xff1a; sqlplus sys/docar…

android mysql sqlite_Android SQLite数据库基本操作方法

程序的最主要的功能在于对数据进行操作&#xff0c;通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的&#xff0c;Android中内置了小巧轻便&#xff0c;功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数据库来实现一…

python 元组遍历_Python中的for循环:元组、列表、字典的遍历和相互转化

Python for循环可以遍历任何序列的项目&#xff0c;如列表、字符串、元组、字典、集合等序列类型。语法&#xff1a;for循环的语法格式如下&#xff1a;for iterating_var in sequence:statements(s)流程图&#xff1a;animals"dog","cat","pig"…

玩转oracle 11g(30):ora-03135和plsql乱码问题

22. ORA-03135连接失去联系 如果应用程序时不时地报错“ORA-03135连接失去联系”&#xff0c; 该问题可能与sqlnet.ora设置参数SQLNET.EXPIRE_TIME 有关 在文件sqlnet.ora中&#xff0c;增加一行&#xff0c;单位分钟&#xff1a; SQLNET.EXPIRE_TIME &#xff1d; 10 23. Pls…

计算机论文搜索技巧【一】

如何搜素一个杂志里面的文章并下载&#xff1f;&#xff08;以FSE为例&#xff09; 1.在dblp搜索 FSE 点击相关链接 用google或 google scholar 跳转页面 2.找到类似 source Materials目录 点击查阅相关文档 找到相关信息 3.复制题目&#xff0c;结合dblp与 google scholar找到…

[众包]Eclipse 运行简单亚马逊AMT模板

教程 1.打开esclipe下载AMT 输入 https://aws.amazon.com/eclipse 下载后需要重启 需要自己在亚马逊先注册 填入分配的信息 注册教程 &#xff08;需要信用卡 激活 创建账号 &#xff09; https://docs.aws.amazon.com/zh_cn/AWSMechTurk/latest/AWSMechanicalTurkGetting…

jmap 文件解析_干货分享丨jvm系列:dump文件深度分析

摘要&#xff1a;java内存dump是jvm运行时内存的一份快照&#xff0c;利用它可以分析是否存在内存浪费&#xff0c;可以检查内存管理是否合理&#xff0c;当发生OOM的时候&#xff0c;可以找出问题的原因。那么dump文件的内容是什么样的呢&#xff1f;JVM dumpjava内存dump是jv…

GAN 的推导、证明与实现。

转自机器之心整理的&#xff0c;来自Goodfellow 在 NIPS 2016 的演讲和台大李弘毅的解释&#xff0c;完成原 GAN 的推导、证明与实现。 本文主要分四部分&#xff0c;第一部分描述 GAN 的直观概念&#xff0c;第二部分描述概念与优化的形式化表达&#xff0c;第三部分将对 GAN …

玩转oracle 11g(32):plsql版本低需到配置文件中添加配置

1创建了一个数据库geyao&#xff0c;但是只能显示docare 2plsql版本太低&#xff0c;或者直接修改 C:\app\MDSD\product\11.2.0\dbhome_2\NETWORK\ADMIN 添加配置文件 出现歌谣

[测试智能合约]ganache+metamask+remix

1.谷歌浏览器 下载metamask 2.设置metamask 增加一个7545端口的网络 3.导入账户 从ganache的accounts里面随便找个账户的私钥传进去 4.打开remix 修改environment 5.写好的智能合约编译 remix经常抽风 疯狂来回切换版本号或者换网络 6.黄色按钮Deploy 7.同一页面最下方 打开部署…

Newtonsoft.Json反序列化(Deserialize)出错:Bad JSON escape sequence

使用Newtonsoft.Json反序列化收到的字串为JObject或其它支持的数据模型&#xff0c;有时错误&#xff0c;提示如下&#xff1a; Bad JSON escape sequence: \c. Path idno, line 5, position 34. 甚纳闷之。遂搜索资料&#xff0c;略有小获&#xff0c;其非法分界符所致。合法的…

玩转oracle 11g(33):无监听程序

故意操作删除监听 直接配置监听即可

mysql安装条款_mysql 安装注意

mysql 远程连接赋予权限&#xff1a;GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIED BY datech WITH GRANT OPTION;FLUSH PRIVILEGES;MySQL 5.1采用了基于密码混编算法的鉴定协议&#xff0c;它与早期客户端(4.1之前)使用的协议不兼容。如果你将服务器升级到4.1之上&#xf…

java学习(126):throw向上抛出异常

//throw抛出异常 import java.util.Scanner; public class test66{static class A {void d() throws Exception {int a, b, c;Scanner in new Scanner(System.in);System.out.println("亲输入a的值");a in.nextInt();System.out.println("请输入b的值");…

[Java]集合的小抄 Java初学者必备

文章目录【背景】CollectionsListArrayList优势操作劣势操作LinkedList优势劣势最基本的两种检索集合中的所有对象的方法&#xff1a;CopyOnWriteArrayList补充说明StackMapMap 的常用方法&#xff1a;HashMapLinkedHashMapTreeMapConcurrentHashMapConcurrentSkipListMap补充说…