多机房数据同步(一致性读写)视频 @Qcon
解决跨数据中心的数据同步和一致性问题,实现跨机房的高可用访问(比如中国特殊网络状况,提供多个数据中心的情况下,解决数据的可用性、一致性)。
解决跨数据中心的数据同步和一致性问题,实现跨机房的高可用访问(比如中国特殊网络状况,提供多个数据中心的情况下,解决数据的可用性、一致性)。
Golang1.1昨天发布,性能提升不少。让我想起去年写的mysql-proxy,于是拿出来又改了一下调用最为频繁的一个函数,发现性能已经非常理想。这里放出来给有兴趣的朋友试用。
目前支持的功能是读写分离(非事务,如果用事务的话不会分发到slave上)和slave的负载均衡,未做失效检查。另外prepare可能会有问题。
如果有什么需求可以后续添加,golang改起来非常方便,当初这个proxy我也就1个礼拜完成的。
下载地址:http://www.mysqlab.net/products/mysql-proxy/lbproxy64.tar.gz (linux 64位)
(有需要win版本的可以密我)
配置:
1. 需要配置用于连接proxy的用户名和密码(sha1(plain password))
2. 需要配置连接后端master和slave的用户和密码(sha1(plain password))
3. slaves需要按照proxy.ini 格式写,因为解析ini文件的目前还没有容错
(本来是打算配置用web界面来做的,被其他事情给耽搁了)
启动:
目前启动方式很山寨
cd /path/to/proxy && ./proxy
(这个容易改,我已经有现成的python manager,套用过来就行)
大家有什么反馈可以q我或者这里留言(第一次需要审核,防止垃圾广告。)
最近用Go语言写给legendbase.com写网站的时候实现了个MVC框架,原理是根据uri请求,用reflect方法找到相应的controller跟method,然后执行之.当没有找到就根据uri后缀是否是php,如果是则调用fastcig-client执行配置目录下的php文件.如果再没有就写404错误. Go语言官方package没有client的实现,于是花了点功夫实现了个,开源出来,给需要的朋友节省点时间.
地址: http://code.google.com/p/go-fastcgi-client/
使用示例:
reqParams := "name=value"
env := make(map[string]string)
env["REQUEST_METHOD"] = "GET"
env["SCRIPT_FILENAME"] = "/Users/ivan/work/test/fcgi/test.php"
env["SERVER_SOFTWARE"] = "go / fcgiclient "
env["REMOTE_ADDR"] = "127.0.0.1"
env["SERVER_PROTOCOL"] = "HTTP/1.1"
env["QUERY_STRING"] = reqParams
fcgi, err := fcgiclient.New("127.0.0.1", 9000)
if err != nil {
fmt.Printf("err: %v", err)
}
content, err := fcgi.Request(env, reqParams)
if err != nil {
fmt.Printf("err: %v", err)
}
fmt.Printf("content: %s", content)
}
Go语言1.0出来之后,原来可用的MySQL驱动在新版本上基本不可用了,于是这几天自己写了个简单的MySQL的驱动,暂不支持prepare,没有implement sql/driver. 或许有能用的上的朋友,所以分享出来. 先介绍用法,后面提供下载链接.
先直接上例子
import (
"log"
"liblbmysql"
)
func main() {
settings := make(map[string]interface{})
settings["host"] = "localhost"
settings["port"] = 3306
settings["uname"] = "ivan"
settings["pass"] = "******"
settings["dbname"] = "test"
settings["charset"] = "utf8"
conn, err := liblbmysql.Connect(settings)
if err != nil {
log.Fatal("Connect to MySQL error: %v", err)
}
var qr *liblbmysql.QueryResult
qr, err = conn.ExecuteFetch("select * from ivan")
if err != nil {
log.Printf("query error: %v", err)
} else {
for {
m := qr.FetchMap()
if m != nil {
log.Printf("row map: %v\n", m)
} else {
break
}
}
}
qr.Free()
conn.Close()
}
package main
import (
"syscall"
"os"
"log"
)
func daemon(nochdir, noclose int) int {
var ret, ret2 uintptr
var err uintptr
darwin := syscall.OS == "darwin"
// already a daemon
if syscall.Getppid() == 1 {
return 0
}
// fork off the parent process
ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
if err != 0 {
return -1
}
// failure
if ret2 < 0 {
os.Exit(-1)
}
// handle exception for darwin
if darwin && ret2 == 1 {
ret = 0
}
// if we got a good PID, then we call exit the parent process.
if ret > 0 {
os.Exit(0)
}
/* Change the file mode mask */
_ = syscall.Umask(0)
// create a new SID for the child process
s_ret, s_errno := syscall.Setsid()
if s_errno != 0 {
log.Printf("Error: syscall.Setsid errno: %d", s_errno)
}
if s_ret < 0 {
return -1
}
if nochdir == 0 {
os.Chdir("/")
}
if noclose == 0 {
f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
if e == nil {
fd := f.Fd()
syscall.Dup2(fd, os.Stdin.Fd())
syscall.Dup2(fd, os.Stdout.Fd())
syscall.Dup2(fd, os.Stderr.Fd())
}
}
return 0
}
// usage example: daemon(0, 0)
参考:http://code.google.com/p/go/issues/detail?id=227
最近评论