SVN负载均衡方案

由于svn是集中式管理的,所有的读取写入都需要集中到一台服务器,但是当使用人数相当庞大时,一台服务器很难支撑,因此就需要想办法实现SVN服务器集群的负载均衡。

国外有一家公司专门提供SVN负载均衡的解决方案,由于是商业解决方案,因此从网站上看不到任何解决次问题的技术文档,而国内压根搜不到这类文章,但是很多公司一定在使用集群式的SVN,例如Google的Code,如此庞大的请求量,如果每个repo都仅靠一台服务器很难支撑,但是也办法知道Google是如何解决的。

我自己瞎折腾出一个方案,不过只能说是雏形,其中可能还会涉及auth缓存以及auth信息如何在多集群间传递而不中断用户操作,各位看官路过如果有建议或者发现问题非常欢迎指出。

方案很简单,由于svn大部分都是update或者checkout请求,而commit这种写操作相当非常少,思想就是读写分离,提高svn的性能想到一个方法就是类似DB的读写分离。因为svn这种集中式管理的仓库,写还是必须写到同一地方,但是读取仓库内容可以分散到多个备库,减轻主库压力,而且大部分请求都是读取,写入请求相当很少。

而读写分离的方法也很直接,通过Nginx或HAProxy在前端根据请求方法进行转发,把写请求转发到SVN Master,同时实时同步到SVN Slave,而读请求转发到SVN Slave集群。读写分离后,从所有请求都一台SVN服务器处理变为由多台SVN服务器同时提供服务,由此解决大量用户更新代码或检出代码使SVN服务器负载彪高,检出代码缓慢的情况。

当commit新版本后,svnmaster同步到svn slave,由于需要同步多台备库,在主库提交完后,需要等待post-commit钩子执行完毕后返回才能算提交完成,如果同步备库很多以后,直接在post-commit钩子中执行svnsync的方法会导致用户提交代码等待时间过长。这里可以采用钩子中像本地的一个daemo程序发送一个请求后直接返回,后daemo程序去执行同步。

大概的架构图如下:
svn负载均衡
通过网络LB设备将请求分发到两台Nginx,如果一台Nginx crash,由LB设备健康检查到后自动踢出,然后通过Nginx根据请求方法进行转发,Nginx的upstream也可进行健康检查,如果一台备库crash也可自动踢出。

还需要写脚本检查备库与主库直接的同步状态,如果失败并多次重新同步失败,需要踢出备库集群,这个可直接修改nginx配置中upstream后reload即可。

废话了一大篇,下面讲解一些实际配置:

首先为了保证用户从多个备库读取数据能正常,备库启动后,必须使用svnadmin setuuid将备库和主库的uuid设为同一个

简单的Nginx配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
http
{
upstream svnmaster
{
server master.svn.net:80;
}
upstream svnslave
{
server salve1.svn.net:80;
server salve2.svn.net:80;
}

log_format svn_log '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "forward:$upstream_addr" "$upstream_status" "$upstream_response_time" '
'"$http_user_agent" ';

server
{
listen 80;
server_name svn.net;

location ~ /svn
{
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

if ( $request_method ~* "^(MOVE|COPY|DELETE|LOCK|UNLOCK|MERGE|PUT|POST|PROPPATCH|MKCOL)$" )
{
proxy_pass http://svnmaster;
}
if ( $request_method ~* "^(OPTIONS|PROPFIND|GET|REPORT|MKACTIVITY|CHECKOUT)$" )
{
proxy_pass http://svnslave;
}

access_log /home/log/svn.log svn_log;
}
}
}

这个方法简单测试提交、检出,删除,复制都是没问题的,但是还是测试过在高并发提交下会出现什么问题,如果有需求的朋友可以尝试下,如果有需要改善的地方非常欢迎指出。

P.S. 国外提供商业解决方案的网站,有兴趣的同学可以看一下 http://www.wandisco.com/subversion/clustering

声明: 除非注明,小峰网络遨游记文章均为原创,转载请以链接形式标明本文地址

本博客原创文字只代表本人某一时间内的观点或结论,与本人所在公司没有任何关系。

本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。

第三方若用于商业用途的转载,须取得本人授权。

本文作者:

本文地址:http://xfeng.me/svn-load-balance-solutions/

你可能还对下面文章感兴趣: