Total Pageviews

Sunday 19 February 2012

双机数据一致性的配置

需求大概这样:一个单机上运行的系统,有数据库、文件附件;为了适应国内复杂的网络环境,也为了实现负载均衡以及数据备份,在另外一个机房,加 一台备用服务器。附件上传到主服务器,上传过程不用考虑网络问题。两台服务器都做前端机,用dnspod 可以配置动态域名,实现同一域名下的多台前端 机;如果是客户端的接口服务器,那么客户端上可以获取服务器,轮询服务器。

问题是,如何配置两台机器,让他们能够同时进行数据库的读写,以及附件的读操作。并保证两台机器的数据一致性(即数据库、附件都能一致)

说下自己的想法。
  1. 数据库同步。数据库同步,还是用最经典的主从架构。写主库,读从库,主库到从库做热备份;不过鉴于服务器在不同机房,读操作直接读本地数据库就ok。
  2. 附件同步。三种方案。a) 利用inotify等触发式文件同步的方式实时同步附件。 b) 做反向代理到主服务器。其实可以理解为一个类似于CDN的方案。Nginx 自带的代理模块,可以做 caching reverse proxy。但是nginx的自带的caching reverse proxy 在HTTP请求带有Range参数时,有个HTTP状态码的小问题。详见 http://www.douban.com/note/91375654/
  3. 补充1: 原始方案是大概10年9月写的。我自身已经不用了。现在的解决方案是单机房,客户端连不上主机房A,会去尝试另外一个机房B的服务器。B只是A的HTTP反向代理。
  4. 补充2: 如果需要保证服务质量,并降低单点压力,那么需要考虑 IDC双写+数据同步了。数据的一致性是个难题。详见 @timyang多IDC的数据分布设计(一)
FROM http://liruqi.wordpress.com/2010/09/15/%e5%8f%8c%e6%9c%ba%e6%95%b0%e6%8d%ae%e4%b8%80%e8%87%b4%e6%80%a7%e9%85%8d%e7%bd%ae/
 

------------------------------------------------------------------------------------------

发现nginx使用反向代理时,返回状态码的BUG

2010-09-17 17:16:11
今天发现的。有空刚才google了一下,似乎有人也遇到类似的问题。http://forum.nginx.org/read.php?2,8958,8958 。Igor Sysoev 回复说,这个问题改不掉。

备用服务器 s.goapk.com 上带缓存的反向代理的配置:

server {
    listen   8003 default;
    server_name  gomarket.goapk.com;

    access_log  /data/logs/gomarket.goapk.com.8003.access.log;
    error_log  /data/logs/gomarket.goapk.com.8003.error.log;
    
    location / {
        proxy_pass http://118.194.24.3:8003;
        proxy_cache my-cache;
        proxy_cache_valid  200 302  60m;
        proxy_cache_valid  404      1m;
    }
}

往主服务器(118.194.24.3) 上上传了一个附件。此时备用服务器还没有缓存。

第一次请求,从HTTP协议上来讲,应该是返回206的,结果返回200:
root@scratchbox:/data/www/wwwroot# curl -svo/dev/null -r0-1024 http://s.goapk.com:8003/apkfile/5bc28fef8184e428e69301d0c13156c5.apk
* About to connect() to s.goapk.com port 8003 (#0)
*   Trying 211.162.69.236... connected
* Connected to s.goapk.com (211.162.69.236) port 8003 (#0)
> GET /apkfile/5bc28fef8184e428e69301d0c13156c5.apk HTTP/1.1
> Range: bytes=0-1024
> User-Agent: curl/7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: s.goapk.com:8003
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx
< Date: Fri, 17 Sep 2010 09:00:01 GMT
< Content-Type: application/octet-stream
< Connection: keep-alive
< Content-Length: 1171049
< Last-Modified: Fri, 17 Sep 2010 08:58:37 GMT
< Accept-Ranges: bytes
< 
{ [data not shown]
* Connection #0 to host s.goapk.com left intact
* Closing connection #0

第二次请求,返回正常:
root@scratchbox:/data/www/wwwroot# curl -svo/dev/null -r0-1024 http://s.goapk.com:8003/apkfile/5bc28fef8184e428e69301d0c13156c5.apk
* About to connect() to s.goapk.com port 8003 (#0)
*   Trying 211.162.69.236... connected
* Connected to s.goapk.com (211.162.69.236) port 8003 (#0)
> GET /apkfile/5bc28fef8184e428e69301d0c13156c5.apk HTTP/1.1
> Range: bytes=0-1024
> User-Agent: curl/7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: s.goapk.com:8003
> Accept: */*
> 
< HTTP/1.1 206 Partial Content
< Server: nginx
< Date: Fri, 17 Sep 2010 09:00:26 GMT
< Content-Type: application/octet-stream
< Content-Length: 1025
< Connection: keep-alive
< Last-Modified: Fri, 17 Sep 2010 08:58:37 GMT
< Content-Range: bytes 0-1024/1171049
< 
{ [data not shown]
* Connection #0 to host s.goapk.com left intact
* Closing connection #0 
 
FROM http://www.douban.com/note/91375654/ 

No comments:

Post a Comment