-
Notifications
You must be signed in to change notification settings - Fork 323
FAQ
readme.md中对Cetus进行了初步的介绍,让大家了解Cetus是做什么的、它主要具备哪些功能特性,以及关于它的一些详细说明的链接和如何反馈给我们问题。
针对详细说明
a 如果是想快速了解Cetus的使用方法,可以参考“Cetus安装与使用”中
- 1.Cetus快速入门
- 2.Cetus安装说明
- 3.Cetus读写分离版配置文件说明
- 4.Cetus分库(sharding)版配置文件说明
- 5.Cetus启动配置选项说明
- 6.Cetus使用约束说明
b 如果是想进阶地学习如何使用Cetus,可以针对不同的版本,查看“Cetus安装与使用”中5-8的使用和管理手册
- 针对读写分离版本可参考
- 7.Cetus读写分离版使用指南
- 8.Cetus读写分离版管理手册
- 针对分库版本可参考
- 9.Cetus分库(sharding)版使用指南
- 10.Cetus分库(sharding)版管理手册
其中在使用指南中会详细介绍Cetus的安装部署步骤、可实现的功能、使用注意事项和应用示例,管理手册中会详细介绍Cetus管理插件的具体使用方法,更好地帮助大家了解Cetus
c 如果想了解Cetus架构与设计,可参考“Cetus架构与设计”中的“Cetus架构和实现”
d “Cetus发现的MySQL xa事务问题”中的“MySQL xa事务问题说明”介绍了在cetus测试过程中发现的MySQL的xa事务的bug,针对该问题,可参考“Cetus辅助”中的“Cetus xa悬挂处理工具”进行处理
e “Cetus辅助”中还有一些其他辅助说明,如果想了解Cetus如何使用改进过的mha实现高可用可参考“Cetus+mha高可用方案”,如果想打Cetus的rpm包可参考“Cetus rpm说明”
f “Cetus测试”提供了我们对Cetus的测试报告
Cetus的文档会不断完善,更方便大家快速的学习、部署、维护。
当利用Lvs集群部署Cetus的情况下需要对Cetus进行维护时,需要在集群中先下掉要维护的Cetus,维护后再将其加入到集群中,步骤如下:
1 利用keepalived将需要维护的Cetus在Lvs集群中的权重改为0
2 确认Lvs集群中需要维护的Cetus权重变为0后,通过管理端口将该Cetus设为维护状态(执行指令:set maintain true)
3 在管理端口查看该Cetus的连接是否还处于事务中(执行指令:show connectionlist),确定并无处于事务中的操作(Trans字段为N)才可将其kill掉进行版本升级等维护操作
4 维护完成后,将新的Cetus起起来
5 利用keepalived将维护完成的Cetus在Lvs集群中的权重改回原来的权重
Cetus自身的高可用,目前线上主要使用的是LVS。
读写分离版本,无法识别的SQL直接发到主库;分库版本,直接报错。
Cetus与后端数据库的交互,使用的是MySQL协议,凡是支持MySQL协议的数据库,理论上Cetus都支持。
同一个session,如果前一条SQL是DML且对数据产生了更新(effect_rows>0),则随后的第一条SQL会自动路由主库,保证同一session写后立即读的数据一致。不同session,Cetus后续会开发一致性读方案,支持多session间的一致性读。
MySQL实例的sql_mode有设置only_full_group_by;Cetus分库版本不支持sql_mode为only_full_group_by。
支持。
Cetus的admin接口目前已经适配了python的MySQLdb模块和pymysql模块。具体使用例子,可以参考Cetus快速入门 。
proxy-backend-addresses=A:3306@data1,B:3306@data2,A:3306@data3,B:3306@data4
Cetus不支持一个后端同时属于两个组。假如只有两个后端,就分两个组即可。
2018-06-08 12:04:32: (message) Update heartbeat error: 1142, text: INSERT, UPDATE command denied to user 'xxx'@'1xxx.250' for table 'tb_heartbeat', backend: 1111:3306
tb_heartbeat是心跳表,主要用于监控主从延迟。上述报错是由于配置的default-username没有tb_heartbeat表的权限,需要grant权限。详细例子可以参考Cetus MySQL准备说明 。
2018-06-08 11:10:21: (warning) no password for cetus_app, monitor will not work
该报错主要是由于在users.json文件中没有配置default-username的密码信息。在users.json中配置对应的账号密码即可。
2018-06-08 11:22:39: (critical) proxy needs default username
该报错是由于在proxy.cnf文件中没有配置default-username。在proxy.cnf中配置好对应的该参数,重启Cetus即可。
目前没有,但是Cetus提供了丰富的admin端口API,大家可以自行实现、接入运维平台。
在使用Cetus分库版本时,由于需要分布式事务支持,因此建议使用5.7及其以上版本;读写分离版本5.6及其以上都可以。
将参数group-replication-mode=1
即可。具体可以参考启动配置选项相关说明。
MySQL端的 max_connections 和 max_user_connections 需要根据 业务最大量 预估。Cetus的默认创建的连接数default-pool-size,只是该backend提供线上服务时,Cetus 预加载 的 默认连接数 。
[root@node3 cetus]# /opt/app/cetus/libexec/cetus --defaults-file=/opt/app/cetus/conf/proxy.conf --conf-dir=/opt/app/cetus/conf
/opt/app/cetus/libexec/cetus: error while loading shared libraries: libmysql-chassis.so: cannot open shared object file: No such file or directory
启动Cetus时候,需要使用bin/cetus
脚本来启动,正确启动命令如下:
/opt/app/cetus/bin/cetus --defaults-file=/opt/app/cetus/conf/proxy.conf --conf-dir=/opt/app/cetus/conf
proxy的登录账号配置方法两种:1 Cetus 启动前,配置在users.json中; 2 已经启动Cetus后,可以通过admin端口动态新增账号。
首先,登录admin端口,执行命令select * from backends
查看后端DB的状态是否是UP状态。这种报错情况下,DB状态应该不是UP状态。
然后查看Cetus启动日志,关注日志中的critical
或warning
日志信息。大多数该问题主要是由于默认账号default-username没有配置好。日志中报错信息:
(critical) src/network-backend.c:388: no required password here for user:test
如果出现上述信息,需要在users.json中对test账号配置相关的密码,重启Cetus;或是admin端口动态配置账号信息。
该参数设置为true时,仅路由到后端主库,除非利用注释强制走从库。
视图基本操作Cetus是支持的。
都有用,读写分离略多一些。
该参数已经去掉了,请忽略。
默认多余的连接,只要不超过最大连接数,都会放入连接池中,连接池中的连接会有生存周期;如果设置了reduce-conn参数,则会关闭多余连接。
凡是不适合数据库中间件处理的SQL,一律拒绝;剩下的,结果集一般都可以线性汇合,而且利用tcp stream特性,可以尽量降低对内存的消耗。结果集如果很大,必须采用tcp stream来避免oom发生。结果集合并这一块,在开源数据库中间件领域还是很领先的。
可以,通过default-pool-size配置。
Cetus在连接池这块做了很多优化,为MySQL和Cetus本身的角度考虑。
- 例如:减少后端并发连接数量
比如分库版本:
用户发送set autocommit = 0,事务1,commit,等待,事务2,commit,等待,事务3,commit
cetus映射为:
start transation,事务1,commit,等待,start transation 事务2,commit,等待,start transation 事务3 commit
当执行事务1的时候,一旦commit完成,就把后端连接放入连接池,方便复用。
- 例如:利用MySQL的local cache服务
在Cetus中,用户访问后端尽量避免切换连接。
Cetus实例都是独立的服务(进程),每个Cetus进程实例,都是靠 IP+PORT来区分的。Cetus可以部署在同一台宿主机上,也可以部署到不同宿主机上(如容灾)。Cetus开放了admin端口和proxy端口。admin端口用来对Cetus进行配置、管理、监控;proxy端口用于业务连接进行正常的SQL存取。
keeplive是Cetus的一个配置参数,配置该参数为true时候,Cetus崩溃的时,会将Cetus重新启动。
default-pool-size是Cetus启动时,默认的预加载的线程池线程数量;max-pool-size是线程池最大允许的线程数量。默认情况下max-pool-size是default-pool-size 的两倍大小。
在master和node主机节点分别安装,可以参考文档cetus + mha高可用方案。
如果只用到了 读写分离版本的话,不需要这个工具;如果使用了sharding版本的分库功能,需要使用这个工具。
可以参考Tcpdump在数据库中的使用实践。
Cetus内存管理建议使用tcmalloc,稳定且使用完的内存会自动释放。
假如有3个 mysql(不考虑主从)。这3台mysql承载均等数据,比如每台mysql 都承载500W数据,这个时候update、delete的操作范围比较大,会跨越的这3台mysql上操作。假如其中一台MySQL的操作失败了,这台失败的mysql事务理应会回滚,那么其他2台mysql如何处理事务?
如果都在一个事务内,有一台MySQL的操作失败了,所有参与分布式事务的操作都会回滚。
我们利用release版本,采用tcmalloc,性能跟oneproxy单线程对比了一下,性能差不多 性能越高,sy越高。sy较高多数是由于网络IO开销。
单个实例的限制。
目前暂时只是这样的,后面也许会考虑类似MySQL这种,加到service里。service mysql stop 其实也是通过kill pid做的,所以目前这中方式也没有问题,大家放心使用。
使用ldd命令查看Cetus链接的库中有没有tcmalloc,例如:
ldd /home/gaohaitao/cetus_install/libexec/cetus
由于架构不太一样,短期没有考虑。
Cetus的扩容有专门的配套脚本工具,方案可以参考文章 网易分片中间件cetus扩容方案。
Cetus目前不支持分表,近期也不会支持。
现在是需要短暂的停一段时间线上业务;完全不停机的迁移,有点复杂,而且风险不好控制。
Cetus目前是单进程的。目前在开发多进程版本,而非多线程。多线程版本开发参考Nginx,使用内核3.9的SO_REUSEPORT机制,完美解决短连接性能瓶颈问题。
域名应该是支持的。
目前MySQL高可用是通过MHA保障的,相关的脚本也已经开源。目前Cetus也支持MGR单主模式,后端集群是MGR时,不再需要MHA保证主库包可用。
支持的,可以通过admin端口对Cetus主从IP进行变更。
Cetus与客户端交互通过MySQL协议,所以支持任何使用MySQL协议的客户端语言进行访问。
一个mysql组代表一个分片。如果只有一个mysql主库,那么这个组就代表这个主库;如果是一主多从,那么这个组代表的是一主多从。每个组里面1个或多个实例,数据是一样的。
可以看下我们的测试报告:Cetus 测试报告。
关于Cetus的IP白名单和黑名单的逻辑大概是这样: 客户端的IP,首先检测是否在白名单,如果在,则允许连接;若不在,则检测是否在黑名单,如果在黑名单,则被拒绝。如果既不在黑名单又不在白名单,则默认允许。
可以尝试在设置白名单基础上,设置黑名单如下:
add deny_ip proxy *;
是的。因为app连接Cetus,Cetus再连接DB,所以DB中的授权IP需要设置Cetus的IP,如果多个Cetus,需要设置多个。Cetus不支持IP透传。
在Cetus中,账号大体可以分两类:1 监控后端DB状态的账号(default-username) 2 业务端访问DB存取数据的账号。这两类账号都需要:1 在Cetus的users.json中配置 2 在MySQL中进行授权。 第2类账号的MySQL端授权根据业务访问的库表进行授权就行,注意授权时,IP授予Cetus的IP(user@'cetus-ip')。MySQL目前支持IP白名单(show allow_ip proxy;)用来限制客户端连接Cetus,目前已经支持IP段的设置。IP白名单不设置,则对客户端IP无限制,如果设置了,则只允许在IP白名单中的客户端IP访问。
可以不用重启,直接登录Cetus的admin端口执行命令: update user_pwd set password='xx' where user='' 和 update app_user_pwd set password='xx' where user='' 动态的增加账号信息就可以,实时生效,且自动保存到users.json中。
这里的 update 命令虽然是“update”,但是当没哟匹配的条件时,功能类似“insert”。
配置如下:
proxy-read-only-backend-addresses=10.10.240.203:3306
proxy-read-only-backend-addresses=10.10.240.146:3306
Cetus读取配置文件*.conf时,如果有相同的配置项(例如proxy-read-only-backend-addresses),会以后面的配置项的值为准,因此只会显示最后一条配置信息。多个从库只需要用逗号隔开,这样配置从库:
proxy-read-only-backend-addresses=10.10.240.203:3306,10.10.240.146:3306
不需要。如果MySQL集群不是主从,配置文件中不需要配置check-slave-delay。如果配置了该参数,就需要配置延迟检测库,不然日志中会循环报错。
报错信息如下:
2018-05-19 21:19:30: (warning) no password for cetus_app, monitor will not work。
该问题主要是由于users.json文件中没有配置cetus_app的密码,需要在users.json中配置正确的账号信息,重启Cetus即可。
没有适配过,后续会考虑。
目前没有适配Windows,可以装一个虚拟机玩玩。
cetus支持的注释比较多,有主从选择、分库路由、单机事务等,所以用了统一的键值形式,便于使用也便于解析,避免出错,master这种形式现在不考虑支持。前Cetus 强制读路由 主库,可以 SELECT /*#mode=READWRITE*/ XXX;
正常情况还是复用的,如果事务出错了,会关掉后端连接。
MySQL 5.7对于分布式事务的支持变得完美了,而且修复了需要相关的bug。可以参考该文章: MySQL 5.7 完美的分布式事务支持。
65 读写分离模式下,客户端连接cetus proxy端,开多个连接。这种情况下,只读操作,会在多个read-only backend实例之间循环吗。我测试了下,好像只能固定连接某个read-only backend。反过来问,有办法实现多个read-only backend的轮训读取吗?
单个前端使用,会保持后端连接,也就是(前端连接 + 后端连接)这个pair尽量不切换,减少切换带来的开销。但整体上,前端的众多请求到后端的配对过程是有轮询的,以保证后端只读库均匀使用。
主从延迟影响有几个:1)如果读请求发到从库,查到的数据不是最新的。2)如果cetus配置了主从延迟达到阈值,读请求就发到主库,那么主库会承担所有的读流量。3)如果延迟的时候主库挂了,mha做切换前需要先把数据追平。
Cetus使用C开发的,辅助脚本有些是Python。
68 plugins/proxy/proxy-plugin.c:160, con:0x17faa00 read query result timeout, sql:SELECT 这个需要延长哪个超时?
尝试修改下proxy-read-timeout参数。
Cetus本身的高可用。
怎么连接原生MySQL,就怎么连接Cetus。
centos上一般如下安装:
yum install google-perftools.x86_64
目前不支持,以后会考虑。
这个功能也会加入的,安全防御这方面,凡是大家提的需求,我们会认真考虑的。
cetus有读写分离和分片版本,分片版本能解决写压力大的问题。
Cetus目前已经支持admin端命令:save settings;用于将动态修改的参数保存到配置文件。
现象正常。一个sql请求,主要的查询压力在数据库端,数据库的cpu使用率高是正常的。
介于普通事务和分布式事务之间,开销会大大小于分布式事务。单个节点为啥不用 普通事物呢?因为当你看到第一条语句的时候,你并不知道后面的sql语句是否会访问其它的节点,只有commit的时候,才能确认。
single-primary mode 下,整个mgr集群也是一主多从的结构。只不过之前主库高可用,使用mha做保障;开启mgr后,mgr自己内部保证主高可用。因此,single-primary mode 下,cetus同样可以提供读写分离,数据分片等各种功能。
如果仅仅访问一个node,那么就会利用这个one phase来优化性能,一阶段提交。
大流量场景下,Cetus可以部署多个实例。
都是网易开发人员,全职开发,网易乐得大量项目使用,分库版本,目前据我所知,4个项目在使用,后续还会应用于更多的系统中。
配置文件如下:
proxy-address=IP:1234 proxy-backend-address=IP:3306@data1
这个选项是个复数形式:proxy-backend-addresses,就算你只配一个,它还是复数形式。
报错信息如下:
在包含自 /data/cetus-master/src/chassis-mainloop.c:45 的文件中:
/data/cetus-master/src/network-mysqld.h:39:19: 错误:mysql.h:没有那个文件或目录
In file included from /data/cetus-master/src/chassis-mainloop.c:45: /data/cetus-master/src/network-mysqld.h:195: 错误:字段‘command’的类型不完全
/data/cetus-master/src/network-mysqld.h:619: 错误:字段‘cur_command’的类型不完全
make[2]: *** [src/CMakeFiles/mysql-chassis.dir/chassis-mainloop.c.o] 错误 1
make[1]: *** [src/CMakeFiles/mysql-chassis.dir/all] 错误 2
make: *** [all] 错误 2
可能没有安装mysql-devel。
报错信息:
2018-03-30 19:51:45: (critical) JSON format is not correct! 2018-03-30 19:51:45: (critical) sharding configuration load error. exit program
users.json使用的cJSON库,不支持注释。上述问题应该是注释导致的。
报错信息:
/data/home/kidzhang/cetus-master/libexec/cetus: error while loading shared libraries: libmysqlclient.so.20: cannot open shared object file: No such file or directory
使用下面命令,看一下链接的库的实际路径,然后建立软链。
ldd libexec/cetus | grep mysql
cetus这个方案 可以,详见文档:cetus + mha高可用方案 。
报错信息:
ERROR 1045 (28000): Access denied for user [email protected]:35661 (using password: YES)
排查时,在Cetus所在机器上,使用相同的账号直连MySQL,确保该账号已经在MySQL端授权。授权没问题,检查下users.json文件中是否配置正确。
存储过程没有做大规模测试。因为我们这逻辑都是在应用端实现,mysql禁止使用存储过程的。
是的。
连接池 肯定是标配,cetus是有的,而且做了一些优化。连接池目的主要有这几点:1 对DB屏蔽 客户端连接数的波动,使得DB连接数小于客户连接数(连接复用)且维稳在一定的数量上 ,保证DB性能稳定;2 减少与DB新建连接时TCP握手造成的耗时 等等。
github上面有测试文档,稳定性如何,可以利用tcpcopy进行流量复制来检验: https://github.com/session-replay-tools/mysql-replay-module。
报错信息:
[root@mysql8 bin]# ./cetus --defaults-file=../conf/proxy.conf [root@mysql8 bin]# 2018-03-27 15:50:42: (critical) proxy needs defaults username.
配置文件中配置:
default_username=admin
变量名字写错了,Cetus无法识别。配置文件中的变量名字中,一律是中划线!
不需要,排序操作是由MySQL处理的。cetus自身除了做线性排序,其它对结果集的各种排序都是拒绝的。
这次一起全部开源,作为整体解决方案。如果不使用我们提供的,你也可以根据你自己的 高可用 环境,自己定制化开发也是可以的。
不支持。
select * from (select col1,col2 from shard_table where col3 = value and col4 =value order by col2 desc limit 100) as temp group by col1 order by col2 desc limit 20;
不支持,这种类似的语句,直接拒绝了。
只要不跨多个库的join,都支持,如果实现跨多个库的join,这种就容易带来新的坑,性能抖动。
嗯,荣誉数据需要手工删除。
Cetus与后端DB是通过MySQL协议交互的,协议一样,都支持。
对,只要确保分布式事务比例不要太高,业务方面设计合理。
使用的是mysql的xa机制,用户发送普通的sql语句,我们转换成xa语句,对用户透明。
参数 | 含义 | 单位 |
---|---|---|
max-alive-time | 后端连接最大存活时间 | 秒 |
slave-delay-down | 从库延迟超过该值,状态将被设置为DOWN | 秒 |
slave-delay-recover | 从库延迟少于该值,状态将恢复为UP | 秒 |
default-query-cache-timeout | 设置query cache的默认超时时间 | 毫秒 |
default-client-idle-timeout | 客户端最大空闲时间 | 毫秒 |
long-query-time | 慢查询记录阈值 | 毫秒 |
proxy-connect-timeout | 连接超时 | 秒 |
proxy-read-timeout | 读超时 | 秒 |
proxy-write-timeout | 写超时 | 秒 |
各个参数的相关说明,可以详见启动配置选项文档。
日志如下:
2018-06-26 11:15:19: (message) starting cetus 1.0.0
2018-06-26 11:15:19: (message) glib version: 2.28.8
2018-06-26 11:15:19: (message) libevent version: 1.4.13-stable
2018-06-26 11:15:19: (message) config dir: /usr/local/cetus/conf
2018-06-26 11:15:19: (message) read 3 users
2018-06-26 11:15:19: (message) src/cetus-master/src/chassis-unix-daemon.c:127: [angel] we try to keep PID=11635 alive, nprocs:0
2018-06-26 11:15:19: (message) plugin proxy 1.0.0 started
2018-06-26 11:15:19: (message) plugin admin 1.0.0 started
2018-06-26 11:15:19: (message) set default pool size:20
2018-06-26 11:15:19: (message) set max pool size:300
2018-06-26 11:15:19: (message) set max resp len:2097152
2018-06-26 11:15:19: (message) set max alive time:3600
2018-06-26 11:15:19: (message) src/cetus-master/src/mysql-proxy-cli.c:572:set merged output size:8192
2018-06-26 11:15:19: (message) src/cetus-master/src/mysql-proxy-cli.c:575:set max header size:65536
2018-06-26 11:15:19: (message) set client_found_rows false
2018-06-26 11:15:19: (message) src/cetus-master/src/mysql-proxy-cli.c:589:xa_log_detailed false
2018-06-26 11:15:19: (message) monitor thread is disabled
日志中显示,监控线程被禁用了。如果监控线程被禁用,就不会监控MGR的node的变化。检查下,配置文件中是否配置了disable-threads=true。如果配置了该参数,去掉该参数,重启Cetus即可。
单点全局表,当时是为了规避有些表频繁修改,防止分布式事务过于频繁。
可以的,cetus在各个分片都会执行建表语句
是的。
全局表的意思是指这个表在每一个group都有一份数据一样的表,全局表数据的插入和更新,是通过分布式事务保证的。
这个要看具体的业务场景。有些业务是join需求比较多,或者是无法确定某些表是否以后都不需要join,那么默认全局表比较好。如果表插入,更新不频繁,做成全局表也无妨。
是的,否则cetus不方便判断。
是的,取模。分片键的类型如果是string类型的话,会有相应的方法,转换成int64,再取模。
set global指令对于中间件,目前是不支持的,如果cetus访问的后端连接切换到其它后端连接,就需要补充上set指令,对连接高效共享使用是不利的。
tcpdump -i any tcp and port cetus端口号 or mysql端口号 -s 0 -w mysql.pcap