用LDAP查找mysql ?

用mysql replication做HA的时候都会遇到一个问题,就是迁移怎么办?比如Master挂了,一个slave被提成Master,那么client怎么知道新Master的IP、端口呢?我一个很自然的想法就是LDAP,或者搞个比它更简单的能完成名字-〉IP的映射即可。

假如协议只选用TCP,连接MySQL需要提供这么4个基本参数:IP、端口号、用户名、密码。因为mysql认证协议很不安全,所以基本上都部署在内网,而内网IP是很富裕的,所以完全可以让每个MySQL分一个IP,都监听在3306。那么只需要完成name –> IP 的映射就足够了。这么一说,所有人自然想到的就是DNS,并且mysql reference manual中推荐的也是DNS,童剑最初用的也是DNS。但我觉得DNS的cache是很一个难控制的东西。

我的想法是用LDAP,或者自己做一个更简单的。完成两个功能:

1、注册IP到名字

2、根据IP查名字

而且这玩意儿效率不必很高。客户端应该做个缓存,缓存中没有的时候才去查。如果是从缓存中读的信息,并且连接失败,那么清掉缓存中这条记录。然后重查重连。

那么这其中就有2个问题:

1、连错了怎么办?

因为缓存是旧的,所以虽然连上了,但实际是连上了另一台MySQL。 我觉得这个问题很简单,在部署的时候保证所有的mysql server的server-id都是不重复的。尤其是对于网游这样的应用,这一点很容易做到。迁移的时候连配置文件一起迁移,于是保证server-id不变。

如果自己有能力改mysql client库,那么就改一下,在连接之前必须设置server-id参数,在接收到服务器发来的第一个包(hello packet)的时候,检查server-id,不正确则断掉。

如果自己没能力改mysql的代码,那么把自己的应用层代码包装下,在连接建立后,手动调用mysql api检查下server id。

如果有5个slave,坏了一个,变成四个?木关系,就按前面说的这套逻辑走。client不是拿着server –id去找ldap要ip、端口号。而是拿着serverid + server group id去查信息。如果这个server-id对应的有机器,那么就告诉它。如果没有,就根据server groupid 查这个server group有哪些IP,server-id分别是什么。

只是这么做,负载均衡策略只有一种:round-robin。而且添新slave的时候,必须由LDAP主动通知一次。好在LDAPv3是支持event的。

2、会使建立数据库连接变慢吗?

不会有明显差别。只要不做迁移,那么cache是一直有效的。在自己本机的内存中查一次map,多快啊。迁移毕竟是很不频繁的事情。但是有一点,有些网管会禁用ICMP,那导致如果对方没有开启此TCP端口,connect函数只能等超时。解决之道:迁走MySQL的同时放一个自己写的fake mysqld。功能很简单,就是accept新TCP连接之后,回一个错误的Mysql packet。大概100行代码之内就能完成。

用LDAP的好处是有现在的server和查询工具、开发库。自己做一个的好处是简单轻巧高效。放一个BDB 1.8x这样的数据库在那就行了,无非就是很简单的插入-查找嘛。把BDB的数据放在一个单独的分区里,用DRBD做复制。每次修改数据的时候强制写完硬盘再返回。多简单啊! 或者用高版本的BDB用它的replication ?

上面是我今天下午刚刚萌生出来的想法,很不成熟,请大家多提意见,拿出批判四人帮的力气使劲批判!

另外我想问一下,腾讯啊sohu啊淘宝啊这些公司,有没有做一套东西把公司的mysql集中管起来?就是童剑在sina研发做的那样的东西?我很想做一个,并且把上文说的该client做的事情做成透明的,使得现有服务无缝迁移。 要不我去google code上建个开源项目?

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥