sql relay 使用
episode01 What Is
此文算是我对这段时间学习SQL Relay的汇总和总结。到此,对SQL Relay的学习也算告一段落了,虽然算不上深入但各方面也基本了解了。另外一点,也许很长时间我不会再怎么折腾SQL Relay了。
SQL Relay是什么东西。只要了解到我是如何知道SQL Relay的,就能非常明确SQL Relay是什么东西了。有一个潜在的项目,此项目只是预期将会达到一种什么规模以及将可能会在某个时期开始。此项目的服务器端将使用PHP,但也可能混 合使用除PHP以外的Java、Python等。数据库方面将是MySQL、PostgreSQL等,当然Oracle也是有可能的。当然目前就我个人而 言最理想的搭配就是PHP加MySQL了。不过PHP没有一个明显的长效的数据库连接池,所有的数据库的连接都内建在PHP内部机制里面,虽然连接速度不 比其他语言慢,但是仍然不是太透明并缺乏定制和管理方法,所以找一个支持PHP的专门提供数据库连接管理的程序是有一定必要的。但是支持PHP的数据库连 接池真的是不好找,也许SQL Relay是唯一的一个。
现在明确了,SQL Relay是一个长效数据库连接池。另外它还是一个数据库连接管理器,还是一个数据库负载均衡器,还是一个数据库连接路由器。好多功能。SQL Relay提供对许多数据库的支持,比如MySQL、PostgreSQL、Oracle、DB2等,连SQLite都支持。SQL Relay提供对许多语言的API,包括PHP、C、C++、Java、Python等。
功能的确是多。显然我最关心的是和PHP有关的部分,对数据库的那边都差不多。
episode02 Install
SQL Relay编译安装是非常容易的,不过首先要安装一个名叫Rudiments的C++库,这个库和sqlrelay是一家的。不需要什么编译选项,直接用 configure和make编译安装就可以了,默认安装位置在/usr/local/firstworks。为了让sqlrelay支持所需要的数据库 和编程语言,在编译之前需要安装相应的头文件。在Fedora下就是mysql-devel、php-devel等,在Ubuntu下大概是mysql- dev这样的。随后就是configure和make编译安装。因为所有的东西都是在默认位置,于是并不需要再指定这些位置。
至少在Fedora里面,当安装完sqlrelay之后,一个服务会被加入并被设定为启动,不过这个服务启动脚本不怎么正常,所以把它关掉吧,使用“chkconfig sqlrelay off”命令。以后我们会写自己的启动脚本。
SQL Relay提供给PHP所使用的module叫sql_relay.so,默认位置在“/usr/lib(64)/php/modules”下,和其他 PHP的module都放在一起,所以让PHP启用这个module也和其他的一样。到“/etc/php.d/”里随便看一看那些文件怎么写就知道了。
episode03 About Config
配置文件默认在“/usr/local/firstworks/etc”,把里面那个“sqlrelay.conf.example”改名或复制成 “sqlrelay.conf”就可以了。这是一个XML格式的配置文件,只需要这个配置文件,你就可以配置使用sqlrelay所提供的所有功能。具体 如何编写这个配置文件,需要翻看官网所提供的document了。因为document是英文的,而且东西也不少,所以初看起来是比较吓人和麻烦的。不过 document提供了些直观的例子,可以加深理解,所以只要努力把document努力看上一遍,就会发现这东西其实并不麻烦,编写属于自己的功能完备 的配置文件是很容易的。在本文中无法细致的讲解这个配置文件的各部份含义以及如何编写,因为那样的话本文将会非常长并且此部分也很有可能成为单纯的翻译 document。所以大家还是不要偷懒了,直接去看document吧。我这种英语很差的人都能看明白,我想大部分人都不会有什么太大障碍的。
有个和配置文件有关的bug,有些人可能会遇到,特别是最初想简单的尝试sqlrelay时。sqlrelay在处理非常简单的配置文件时会有问题。“非 常简单”的意思,是指配置文件里只有一个“<instance>”(实例)。通常初次尝试sqlrelay的时候会只连接一个数据库来启动试 试,此时配置文件里就会只需要存在一个“<instance>”,bug可能会在此情况下发生,造成sqlrelay无法正常启动。解决方法 就是再加一个“<instance>”,这个新加的信息只需要随便伪造就可以了。最简单做法,把自己写的<instance>复 制一遍,然后改一下instance的id就可以了。随着学习实验的继续深入,这个Bug就不会再遇到了。关于这个问题,可参考网址http://sourceforge.net/mailarchive/forum.php?thread_name=59D43F9401ECAC43BD3FADCC97D850A9012643DB%40sysm0030.sysinf.local&forum_name=sqlrelay-discussion,或者我个人之前的文章,里面有错误过程描述:http://www.ydmsh.com/www/Blog/Show/id/148/。
episode04 Start and Stop
SQL Relay的所有命令都在“/usr/local/firstworks/bin”内,当然这是默认位置。SQL Relay的启动过程是非常非常复杂的,所以用到的命令也就非常非常的多了。sqlrelay在安装的过程中,并没有把上面那个路径加入到PATH环境变 量中,而我非常建议你把它自己加入到PATH环境变量中去,因为其中有个叫sqlr-start的命令比较笨。这个问题先不说,首先先看看 sqlrelay启动的步骤是什么样子的。
SQL Relay完整启动需要四大部分:
1.启动监听器,使用“sqlr-listener -id ID”,这里的ID是配置文件中<instance>里的id,PHP等服务端语言连接sqlrelay的时候实际连接到的就是这个监听器;
2.进行数据库连接,这里根据你要连接的数据库种类不同,使用的命令也不同,假如要连接MySQL数据库,使用“sqlr-connection- mysql -id ID -connectionid CONNECTIONID”,里面的ID和第一步的一样,而CONNECTIONID则是配置文件中<connection>里的 connectionid,这一步按照需要肯定要反复执行,配置文件中的有几个<connection>就要至少执行几次(换 connectionid),否则你的那些<connection>就白写了,相同connectionid的也可以按照需要重复执行,为同 样的数据库创建多个长数据连接,最终的效果就是产生多个sqlr-connection-mysql,而每个进程都是一个数据库长连接;
3.启动定标器,使用“sqlr-scaler -id ID”,定标器大概的作用是,看第二步所产生的数据库连接是否还有空闲,如果都忙碌着则产生新的数据库连接以接受新的查询请求;
4.启动缓存管理,使用“sqlr-cachemanager”,sqlrelay所提供的对查询内容的本地文件缓存由这个进程来负责。
到此为止,SQL Relay就启动完毕了,系统中会增加一系列相应的进程来完成不同的操作。
停掉SQL Relay,比启动它要省事省心的多,只需要执行“sqlr-stop ID”就可以了,此命令会让与这个ID相关的进程一个个逐一结束。但是sqlr-stop不会结束sqlr-cachemanager,sqlr- cachemanager应该是公用的,不和任何ID有关。
SQL Relay还提供一个更简单的启动命令“sqlr-start -id ID”,这个命令将根据配置文件里的内容自动执行上面所有四步启动过程,包括sqlr-connection-mysql需要执行几次。这个命令很省事很 简单,但是如果没有按之前把路径加入到PATH中的话,无论你用绝对路径还是相对路径执行sqlr-start,它都会提示找不到sqlr- listener等命令的,所以说sqlr-start比较笨笨的。
但是一个sqlr-start不能解决所有问题,如果配置文件里有多个<instance>需要启动,那么就要根据不同的ID执行多次sqlr-start,同样关闭的时候也需要多次执行sqlr-stop。
episode05 Realization
在最开始的时候,本文就说到SQL Relay是一个长效数据库连接池,一个数据库连接管理器,一个数据库负载均衡器,一个数据库连接路由器。这些功能实际上是怎么实现的呢?一切的实现都在 sqlrelay的配置文件中。前面也说到了,sqlerlay的配置文件是XML格式的,正是因为这个XML使得一个文本文件却能很紧凑的很容易的塞进 去非常复杂的设置配置。其实也没什么复杂的,一张很简单的拓扑图就能覆盖sqlrelay所能实现的全部功能,下面先放这张图。
看这个拓扑图,的确是非常简单,却也能说明一切。我们假设有四台服务器,一台跑着httpd,一台跑着sqlrelay,两台跑着MySQL。当然完全可 以让sqlrelay区域中的三部分处于不同的服务器上,所以具体如何假设各个服务的物理位置并不重要,重要的仅仅是逻辑关系。图上“sqlrelay区 域”的拓扑结构也不局限于此,这里只摆放了三个典型而已。简单点说,发挥想象力吧。
数据库连接池的功能,这就不需要多说了,一切其他的功能都是依靠数据库连接池,没有这个功能其他的功能都将是浮云。
那么,就先说说数据库负载均衡是如何实现的。在配置文件的每个<instance>里,都可以写若干 条<connection>,每个<connection>是一个数据库连接信息,在sqlrelay启动的第二步 中,sqlrelay进行数据库连接的时候就看这里,按照配置文件内容连接多个数据库,并且与每个数据库都保持多条长连接。当应用程序(假如是PHP)需 要查询数据库的时候,sqlrelay将在所有建立好的数据库连接中轮询,所有的连接都有同等的机率为应用程序提供数据服务。于是,查询被有效的分担到多 台数据库,实现了负载均衡。
数据库路由的实现依靠一个特殊的<instance>,这个<instance>中dbase参数为router,也就是数据库 类型为router。在这个<instance>里面没有<connection>,取而代之的是<route>, 每个<route>内可以写若干SQL匹配条件。我们假设之前建立两个<instance>,一个id为writer连接拓扑图 中的MySQL master专门负责改变数据的操作,一个id为reader连接拓扑图中的两台MySQL专门负责查询数据的操作。然后我们再建立一个router形式 的<instance>,写两个<route>。第一个<route>连接到writer,写条件让 “insert”等开头的查询语句经过这个route。第二个<route>连接到reader,让所有的查询语句通过。因为 “insert”开头的语句会先经过第一个<route>并匹配,所以被路由到了writer,而reader永远不会接收到。而 “select”开头的语句,经过第一个<route>后没有匹配,所以到达第二个<route>后将被路由到reader。路 由就这么实现了,还是非常简单的。匹配条件可以很复杂,可以针对每个具体的数据表进行路由。
数据库连接管理器,这是我自己这么称呼的,好像别的地方并没有这么说。但是,它可以同时连接多种(不仅仅是多个)数据库,还可以跟据查询语言路由,还可以负载均衡,拓扑结构可以无限灵活,难道还称不上管理器吗?
episode06 Speed
SQL Relay的速度,是一个很有意思的问题。用脚指头想想就知道多一个sqlrelay肯定对速度有影响,但到底会慢多少呢?sqlrelay的速度的确是 让人很纠结的。比起程序直接连接数据库,sqlrelay真的是慢很多。与程序和数据库在同一台机器上的情况比较,sqlrelay会多用3倍(大约)的 时间。与程序和数据库在不同机器上的情况比较,sqlrelay仍然会多用0.5倍(大约)的时间。的确是纠结吧,sqlrelay对速度的影响实在是太 明显了。但是这只是在结构非常简单时所得出的结论,采用的结构就是之前那张拓扑图所展示的。另外测试压力也不大,并发连接数不超过100。真正纠结的地方 其实不应该在sqlrelay的速度上,这样的规模根本没有必要使用sqlrelay。sqlrelay的优势并不是速度有多快,当你有一个需要许多许多 数据库服务器的网站时,必须有一个功能足够强大的数据库连接池管理软件时,sqlrelay的必要性才会体现出来,那时这个速度就不是什么问题了。