Ejemplo n.º 1
0
// ./slaveof-proxy -src localhost:6379 -dest remote:6379 -pullrate 400 -pushrate 400
func main() {
	runtime.GOMAXPROCS(4)
	src := flag.String("src", "", "master")
	dest := flag.String("dest", "", "slave")
	pullrate := flag.Int("pullrate", 400, "pull rate in Mbits/s")
	pushrate := flag.Int("pushrate", 400, "push rate in Mbits/s")
	buffer := flag.Int("buffer", 100, "buffer x10000 records")
	flag.Parse()

	if *pullrate < 100 {
		*pullrate = 100
	}
	if *pushrate < 100 {
		*pushrate = 100
	}
	if *buffer < 100 {
		*buffer = 100
	} else if *buffer > 1000 {
		*buffer = 1000
	}

	stdlog.Println("slaveof-proxy 1.0.3")
	stdlog.Printf("from [%s] to [%s]\n", *src, *dest)
	stdlog.Printf("pull [%d] buffer [%d]\n", *pullrate, *buffer)
	stdlog.Println("SYNC ...")

	client, err := NewClient(*src, *dest, *buffer)
	if err != nil {
		stdlog.Println("ERR", err)
		return
	}
	client.SetPullRate(*pullrate / 8 * 1024 * 1024)
	client.SetPushRate(*pushrate / 8 * 1024 * 1024)
	client.Sync()
}
Ejemplo n.º 2
0
// S: SYNC UID [UID] PORT [PORT] SNAP [1/0] SEQ [-1/...]
func (server *GoRedisServer) OnSYNC(session *Session, cmd *Command) (reply *Reply) {
	stdlog.Printf("[S %s] %s\n", session.RemoteAddr(), cmd)

	args := cmd.Args()[1:]
	if len(args) < 2 || len(args)%2 != 0 {
		session.Close()
		return
	}
	for i := 0; i < len(args); i += 2 {
		session.SetAttribute(string(args[i]), string(args[i+1]))
	}

	if !server.synclog.IsEnabled() {
		stdlog.Println("synclog enable")
		server.synclog.Enable()
	}

	// 使用从库端口代替socket端口,标识来源
	h, _ := splitHostPort(session.RemoteAddr().String())
	remoteHost := fmt.Sprintf("%s:%s", h, session.GetAttribute("PORT"))
	session.SetAttribute(S_HOST, remoteHost)
	session.SetAttribute(S_STATUS, REPL_WAIT)

	go func() {
		server.syncmgr.Put(remoteHost, session)
		err := server.doSync(session, cmd)
		if err != nil {
			stdlog.Println("sync ", err)
		}
		session.Close()
		server.syncmgr.Remove(remoteHost)
	}()

	return NOREPLY
}
Ejemplo n.º 3
0
func (server *GoRedisServer) OnAOF(session *Session, cmd *Command) (reply *Reply) {
	defer func() {
		if v := recover(); v != nil {
			stdlog.Printf("aof panic %s\n", cmd)
			stdlog.Println(string(debug.Stack()))
		}
	}()

	onoff := strings.ToUpper(cmd.StringAtIndex(1))
	if onoff == "YES" {
		if server.aofwriter != nil {
			return ErrorReply("aof already inited")
		}
		if !server.synclog.IsEnabled() {
			stdlog.Println("synclog enable")
			server.synclog.Enable()
		}
		go func() {
			err := server.aofStart()
			if err != nil {
				stdlog.Println("aof", err)
			}
		}()
	} else if onoff == "NO" {
		return server.onAOF_NO()
	} else {
		return ErrorReply("must be YES/NO")
	}
	return StatusReply("OK")
}
Ejemplo n.º 4
0
func main() {
	opts := levigo.NewOptions()
	opts.SetCache(levigo.NewLRUCache(128 * 1024 * 1024))
	opts.SetCompression(levigo.SnappyCompression)
	opts.SetBlockSize(32 * 1024)
	opts.SetWriteBufferSize(128 * 1024 * 1024)
	opts.SetMaxOpenFiles(100000)
	opts.SetCreateIfMissing(true)

	db, e1 := levigo.Open("/tmp/rocksdb0", opts)
	if e1 != nil {
		panic(e1)
	}
	stdlog.Println(db)

	batch := levigo.NewWriteBatch()
	batch.Put([]byte("name"), []byte("later"))
	wo := levigo.NewWriteOptions()
	db.Write(wo, batch)

	ro := levigo.NewReadOptions()
	value, err := db.Get(ro, []byte("name"))
	stdlog.Println(string(value), err)

	db.Close()
}
Ejemplo n.º 5
0
func main() {
	srcptr := flag.String("src", "", "source host")
	destptr := flag.String("dest", "", "dest host")
	modePtr := flag.String("mode", "", "r/w/rw")
	flag.Parse()

	if len(*srcptr) == 0 || len(*destptr) == 0 {
		stdlog.Println("must set -src or -dest")
		return
	}
	desthost = *destptr
	mode = *modePtr
	if len(mode) == 0 {
		stdlog.Println("must set -mode [r|w|rw]")
		return
	}

	go runloop()

	r := redis_tool.NewMonitorReader(*srcptr)
	r.DidRecvCommand = recvCommand // bind
	err := r.Connect()
	if err != nil {
		panic(err)
	}
}
Ejemplo n.º 6
0
// go run goredis-server.go -h localhost -p 1602
// go run goredis-server.go -procs 8 -p 17600
// go run goredis-server.go -slaveof localhost:1603
func main() {
	version := flag.Bool("v", false, "print goredis-server version")
	host := flag.String("h", "", "server host")
	port := flag.Int("p", 1602, "server port")
	slaveof := flag.String("slaveof", "", "replication")
	procs := flag.Int("procs", 8, "GOMAXPROCS")
	repair := flag.Bool("repair", false, "repaire rocksdb")
	flag.Parse()

	if *version {
		fmt.Println("goredis-server", goredis_server.VERSION)
		return
	}

	runtime.GOMAXPROCS(*procs)

	opt := goredis_server.NewOptions()
	opt.SetBind(fmt.Sprintf("%s:%d", *host, *port))
	opt.SetDirectory(dbHome(*port))
	if len(*slaveof) > 0 {
		h, p, e := splitHostPort(*slaveof)
		if e != nil {
			panic(e)
		}
		opt.SetSlaveOf(h, p)
	}

	// 重定向日志输出位置
	redirectLogOutput(opt.Directory())

	// repair
	if *repair {
		dbhome := opt.Directory() + "db0"
		finfo, e1 := os.Stat(dbhome)
		if os.IsNotExist(e1) || !finfo.IsDir() {
			stdlog.Println("db not exist")
			return
		} else {
			stdlog.Println("start repair", dbhome)
			levelredis.Repair(dbhome)
			stdlog.Println("repair finish")
		}
		return
	}

	stdlog.Println("========================================")
	server := goredis_server.NewGoRedisServer(opt)
	if err := server.Init(); err != nil {
		panic(err)
	}
	if err := server.Listen(); err != nil {
		panic(err)
	}
}
Ejemplo n.º 7
0
// 初始化入口
func (server *GoRedisProxy) Init() (err error) {
	e1 := server.resetMaster(server.options.MasterHost)
	e2 := server.resetSlave(server.options.SlaveHost)
	if e1 != nil {
		stdlog.Println(e1)
	}
	if e2 != nil {
		stdlog.Println(e2)
	}
	return
}
Ejemplo n.º 8
0
// 初始化leveldb
func (server *GoRedisServer) initLevelDB() (err error) {
	opts := levelredis.NewOptions()
	cache := levelredis.NewLRUCache(128 * 1024 * 1024)
	opts.SetCache(cache)
	opts.SetCompression(levelredis.SnappyCompression)
	opts.SetBlockSize(8 * 1024)
	opts.SetMaxBackgroundCompactions(6)
	opts.SetWriteBufferSize(32 * 1024 * 1024)
	opts.SetMaxOpenFiles(100000)
	opts.SetCreateIfMissing(true)
	env := levelredis.NewDefaultEnv()
	env.SetBackgroundThreads(6)
	env.SetHighPriorityBackgroundThreads(2)
	opts.SetEnv(env)
	db, e1 := levelredis.Open(server.directory+"/db0", opts)
	if e1 != nil {
		return e1
	}
	server.levelRedis = levelredis.NewLevelRedis(db, false)
	server.DeferClosing(func() {
		opts.Close()
		cache.Close()
		env.Close()
		stdlog.Println("db closed")
	})
	return
}
Ejemplo n.º 9
0
func (s *SlaveClient) Sync() (err error) {
	session := s.src
	if err = session.WriteCommand(NewCommand([]byte("SYNC"))); err != nil {
		return
	}

	rdbsaved := false
	for {
		var c byte
		if c, err = session.PeekByte(); err != nil {
			break
		}
		if !rdbsaved && c == '$' {
			if err = s.recvRdb(); err != nil {
				break
			}
			rdbsaved = true
		} else if c == '\n' {
			if _, err = session.ReadByte(); err != nil {
				break
			}
			stdlog.Println("waiting ...")
		} else {
			var cmd *Command
			if cmd, err = session.ReadCommand(); err != nil {
				break
			}
			s.counters.Get("in").Incr(1)
			s.buffer <- cmd
		}
	}
	return
}
Ejemplo n.º 10
0
// 从主库获取数据
func (server *GoRedisServer) OnSLAVEOF(session *Session, cmd *Command) (reply *Reply) {
	// 保障不会奔溃
	defer func() {
		if v := recover(); v != nil {
			stdlog.Printf("[%s] slaveof panic %s\n", session.RemoteAddr(), cmd)
			stdlog.Println(string(debug.Stack()))
		}
	}()
	arg1, arg2 := cmd.StringAtIndex(1), cmd.StringAtIndex(2)
	// SLAVEOF NO ONE
	if strings.ToUpper(arg1) == "NO" && strings.ToUpper(arg2) == "ONE" {
		return server.onSlaveOfNoOne(session, cmd)
	}

	// connect to master
	hostPort := arg1 + ":" + arg2
	conn, err := net.Dial("tcp", hostPort)
	if err != nil {
		return ErrorReply(err)
	}

	// check exists
	remoteHost := conn.RemoteAddr().String()
	if server.slavemgr.Contains(remoteHost) {
		return ErrorReply("connection exists")
	}

	masterSession := NewSession(conn)
	isgoredis, version, err := redisInfo(masterSession)
	if err != nil {
		return ErrorReply(err)
	}

	var client ISlaveClient
	if isgoredis {
		slavelog.Printf("[M %s] SLAVEOF %s GoRedis:%s\n", remoteHost, remoteHost, version)
		if client, err = NewSlaveClientV2(server, masterSession); err != nil {
			return ErrorReply(err)
		}
	} else {
		slavelog.Printf("[M %s] SLAVEOF %s Redis:%s\n", remoteHost, remoteHost, version)
		if client, err = NewSlaveClient(server, masterSession); err != nil {
			return ErrorReply(err)
		}
	}

	// async
	go func() {
		client.Session().SetAttribute(S_STATUS, REPL_WAIT)
		server.slavemgr.Put(remoteHost, client)
		err := client.Sync()
		if err != nil {
			slavelog.Printf("[M %s] sync broken %s\n", remoteHost, err)
		}
		client.Close()
		server.slavemgr.Remove(remoteHost)
	}()

	return StatusReply("OK")
}
Ejemplo n.º 11
0
// 初始化主从日志
func (server *GoRedisServer) initSyncLog() error {
	opts := levelredis.NewOptions()
	cache := levelredis.NewLRUCache(32 * 1024 * 1024)
	opts.SetCache(cache)
	opts.SetCompression(levelredis.SnappyCompression)
	opts.SetBlockSize(4 * 1024)
	opts.SetMaxBackgroundCompactions(2)
	opts.SetWriteBufferSize(32 * 1024 * 1024)
	opts.SetMaxOpenFiles(100000)
	opts.SetCreateIfMissing(true)
	env := levelredis.NewDefaultEnv()
	env.SetBackgroundThreads(2)
	env.SetHighPriorityBackgroundThreads(1)
	opts.SetEnv(env)
	db, e1 := levelredis.Open(server.directory+"/synclog", opts)
	if e1 != nil {
		return e1
	}
	ldb := levelredis.NewLevelRedis(db, false)
	server.synclog = NewSyncLog(ldb, "sync")
	server.DeferClosing(func() {
		opts.Close()
		cache.Close()
		env.Close()
		stdlog.Println("synclog closed")
	})
	return nil
}
Ejemplo n.º 12
0
func (server *GoRedisServer) Init() (err error) {

	server.initSignalNotify()

	stdlog.Println("server init, version", VERSION, "...")
	err = server.initLevelDB()
	if err != nil {
		return
	}
	err = server.initSyncLog()
	if err != nil {
		return
	}
	server.config = NewConfig(server.levelRedis, PREFIX+"config:")
	// monitor
	server.initCommandMonitor(server.directory + "/cmd.log")
	server.initCommandCounterLog("string", []string{"GET", "SET", "MGET", "MSET", "INCR", "DECR", "INCRBY", "DECRBY"})
	server.initCommandCounterLog("hash", []string{"HGETALL", "HGET", "HSET", "HDEL", "HMGET", "HMSET", "HINCRBY", "HLEN"})
	server.initCommandCounterLog("set", []string{"SADD", "SCARD", "SISMEMBER", "SMEMBERS", "SREM"})
	server.initCommandCounterLog("list", []string{"LPUSH", "RPUSH", "LPOP", "RPOP", "LINDEX", "LLEN", "LRANGE", "LTRIM"})
	server.initCommandCounterLog("zset", []string{"ZADD", "ZCARD", "ZSCORE", "ZINCRBY", "ZRANGE", "ZRANGEBYSCORE", "ZRANK", "ZREM", "ZREMRANGEBYRANK", "ZREMRANGEBYSCORE", "ZREVRANGE", "ZREVRANGEBYSCORE", "ZREVRANK"})
	server.initSeqLog(server.directory + "/seq.log")
	server.initLeveldbIOLog(server.directory + "/leveldb.io.log")
	server.initLeveldbStatsLog(server.directory + "/leveldb.stats.log")
	server.initExecLog(server.directory + "/exec.time.log")
	server.initSlowlog(server.directory + "/slow.log")
	stdlog.Printf("init uid %s\n", server.UID())
	server.initSlaveOf()
	return
}
Ejemplo n.º 13
0
func (server *GoRedisServer) onAOF_NO() (reply *Reply) {
	if server.aofwriter == nil {
		return ErrorReply("aof not inited")
	}
	server.aofwriter.Close()
	stdlog.Println("aof closed")
	return StatusReply("OK")
}
Ejemplo n.º 14
0
// 包含w表示可写入,包容rr表示主从均可以读
// mode=r, 从库提供读,写操作返回错误
// mode=rr, 主从均提供读,写操作返回错误
// mode=rw, 主库提供写,从库提供读
// mode=rrw,主库提供写,主从均提供读
func (server *GoRedisProxy) resetMode(mode string) (err error) {
	server.Suspend()
	defer server.Resume()

	stdlog.Println("CONFIG mode", mode)
	server.options.Mode = mode
	return
}
Ejemplo n.º 15
0
// ./slaveof-proxy -src localhost:6379 -dest remote:6379 -pullrate 400 -pushrate 400
func main() {
	runtime.GOMAXPROCS(4)
	src := flag.String("src", "", "master")
	dest := flag.String("dest", "", "slave")
	pullrate := flag.Int("pullrate", 400, "pull rate in Mbits/s")
	pushrate := flag.Int("pushrate", 400, "push rate in Mbits/s")
	buffer := flag.Int("buffer", 100, "buffer x10000 records")
	dbpath := flag.String("dbpath", "/tmp", "rdb path")
	flag.Parse()

	if *pullrate < 100 {
		*pullrate = 100
	}
	if *pushrate < 100 {
		*pushrate = 100
	}
	if *buffer < 100 {
		*buffer = 100
	} else if *buffer > 1000 {
		*buffer = 1000
	}

	stdlog.Println("slaveof-proxy 1.0.4")
	if len(*src) == 0 || len(*dest) == 0 {
		stdlog.Println("Usage: ./slaveof-proxy -src master:port -dest slave:6379 -pullrate 400 -pushrate 400 -buffer 100 -dbpath /tmp")
		return
	}

	stdlog.Printf("from [%s] to [%s]\n", *src, *dest)
	stdlog.Printf("pull [%d] buffer [%d]\n", *pullrate, *buffer)
	stdlog.Println("SYNC ...")

	client, err := NewClient(*src, *dest, *buffer)
	if err != nil {
		stdlog.Println("ERR", err)
		return
	}
	client.SetPullRate(*pullrate / 8 * 1024 * 1024)
	client.SetPushRate(*pushrate / 8 * 1024 * 1024)
	client.SetDbPath(*dbpath)
	err = client.Sync()
	if err != nil {
		panic(err)
	}
}
Ejemplo n.º 16
0
func redirectToGoRedis(cmd *Command) (ok bool) {
	pool := GetRedisPool(desthost)
	conn := pool.Get()
	defer conn.Close()
	args := make([]interface{}, 0, len(cmd.Args)-1)
	for i := 1; i < len(cmd.Args); i++ {
		args = append(args, cmd.Args[i])
	}
	_, err := conn.Do(cmd.StringAtIndex(0), args...)
	if err != nil {
		// io.EOF or "connection refused"
		stdlog.Println("ERR", len(buffer), total, cmd, err)
		return false
	}
	total++
	stdlog.Println(len(buffer), total, cmd)
	return true
}
Ejemplo n.º 17
0
// 处理退出事件
func (server *GoRedisServer) initSignalNotify() {
	server.sigs = make(chan os.Signal, 1)
	signal.Notify(server.sigs, syscall.SIGTERM)
	go func() {
		sig := <-server.sigs
		stdlog.Println("recv signal:", sig)
		server.Close()
	}()
}
Ejemplo n.º 18
0
func (s *SlaveClient) readAllReply() {
	for {
		_, err := s.Dest().ReadByte()
		if err != nil {
			s.dest = nil
			s.destwriter = nil
			stdlog.Println("ReadReply ERR", err)
			time.Sleep(time.Millisecond * 1000)
		}
	}
}
Ejemplo n.º 19
0
func main() {
	src := flag.String("src", "", "source host")
	dest := flag.String("dest", "", "dest host")
	mode := flag.String("mode", "", "r/w/rw")
	flag.Parse()

	if len(*src) == 0 || len(*dest) == 0 {
		stdlog.Println("must set -src or -dest")
		return
	}
	if len(*mode) == 0 {
		stdlog.Println("must set -mode [r|w|rw]")
		return
	}

	monitor := shardredis.NewMonitorRedirect(*src, *dest, *mode)
	if err := monitor.Start(); err != nil {
		panic(err)
	}
}
Ejemplo n.º 20
0
// 关闭服务
func (server *GoRedisServer) Close() {
	server.closing = true               // 标记退出
	server.Suspend()                    // 挂起全部传入数据
	time.Sleep(time.Millisecond * 2000) // 休息一下,Suspend瞬间可能还有数据库写入
	server.levelRedis.Close()
	server.levelRedis = nil // 防止调用
	server.synclog.Close()
	server.synclog = nil // 防止调用
	for e := server.closingFunc.Front(); e != nil; e = e.Next() {
		fn, ok := e.Value.(func())
		if ok {
			fn()
		} else {
			stdlog.Println("closing func err", e.Value)
		}
	}
	time.Sleep(time.Millisecond * 2000) // 休息一下
	stdlog.Println("bye")
	os.Exit(0)
}
Ejemplo n.º 21
0
func (server *GoRedisProxy) resetMaster(host string) (err error) {
	server.Suspend()
	defer server.Resume()

	stdlog.Println("CONFIG master", host)
	if server.master != nil {
		server.master.Close()
	}
	server.options.MasterHost = host
	server.master, err = NewRemoteSession(server.options.MasterHost, server.options.PoolSize)
	return
}
Ejemplo n.º 22
0
func (server *GoRedisProxy) resetSlave(host string) (err error) {
	server.Suspend()
	defer server.Resume()

	stdlog.Println("CONFIG slave", host)
	if server.slave != nil {
		server.slave.Close()
	}
	server.options.SlaveHost = host
	server.slave, err = NewRemoteSession(server.options.SlaveHost, server.options.PoolSize)
	return
}
Ejemplo n.º 23
0
// go run redis-proxy.go -p 1603 -master localhost:6379 -slave localhost:6389
func main() {
	runtime.GOMAXPROCS(8)
	// options
	opt := goredis_proxy.NewOptions()
	// flags
	version := flag.Bool("v", false, "print goredis-proxy version")
	flag.StringVar(&opt.Host, "h", "", "server host")
	flag.IntVar(&opt.Port, "p", 1602, "server port")
	flag.StringVar(&opt.MasterHost, "master", "", "master")
	flag.StringVar(&opt.SlaveHost, "slave", "", "slave")
	flag.StringVar(&opt.Mode, "mode", "rrw", "r/rr/rw/rrw, default rrw")
	flag.IntVar(&opt.PoolSize, "poolsize", 100, "pool for remote server")
	flag.Parse()

	if *version {
		fmt.Println("redis-proxy ", goredis_proxy.VERSION)
		return
	}

	if len(opt.MasterHost) == 0 || len(opt.SlaveHost) == 0 {
		stdlog.Println("bad master/slave")
		return
	}

	stdlog.Println("redis-proxy ", goredis_proxy.VERSION)
	stdlog.Printf("master:[%s], slave:[%s], mode:[%s], poolsize:[%d]\n", opt.MasterHost, opt.SlaveHost, opt.Mode, opt.PoolSize)
	stdlog.Println("listen", opt.Addr())

	// start
	server := goredis_proxy.NewProxy(opt)
	err := server.Init()
	if err != nil {
		panic(err)
	}
	err = server.Listen(opt.Addr())
	if err != nil {
		panic(err)
	}
}
Ejemplo n.º 24
0
func (s *SlaveClient) writeCommand(cmd *Command) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for {
		_, err := s.Writer().Write(cmd.Bytes())
		if err != nil {
			s.dest = nil
			s.destwriter = nil
			stdlog.Println("WRITE_ERR", err, cmd)
			time.Sleep(time.Millisecond * 1000)
			continue
		}
		break
	}
}
Ejemplo n.º 25
0
func (s *SlaveClient) Dest() *Session {
	s.connmu.Lock()
	defer s.connmu.Unlock()
	if s.dest == nil {
		for {
			conn, err := net.Dial("tcp", s.desthost)
			if err != nil {
				stdlog.Println("CONN_ERR", err)
				time.Sleep(time.Millisecond * 1000)
				continue
			}
			s.dest = NewSession(conn)
			break
		}
	}
	return s.dest
}
Ejemplo n.º 26
0
func (server *GoRedisServer) doSync(session *Session, cmd *Command) (err error) {
	// snapshot
	var nextseq int64
	if session.GetAttribute("SEQ") != nil {
		nextseq, err = strconv.ParseInt(session.GetAttribute("SEQ").(string), 10, 64)
		if err != nil {
			return
		}
	}

	remoteHost := session.GetAttribute(S_HOST).(string)

	if session.GetAttribute("SNAP") != nil && session.GetAttribute("SNAP").(string) == "1" {
		session.SetAttribute(S_STATUS, REPL_SEND_BULK)
		if nextseq, err = server.sendSnapshot(session); err != nil {
			stdlog.Printf("[S %s] snap send broken (%s)\n", remoteHost, err)
			return
		}
	}

	if nextseq < 0 {
		nextseq = 0
	}
	if nextseq < server.synclog.MinSeq() || nextseq > server.synclog.MaxSeq()+1 {
		stdlog.Printf("[S %s] seq %d not in (%d, %d), closed\n", remoteHost, nextseq, server.synclog.MinSeq(), server.synclog.MaxSeq())
		return errors.New("bad seq range")
	}

	// 如果整个同步过程s

	stdlog.Println("sync online ...")
	session.SetAttribute(S_STATUS, REPL_ONLINE)
	// 发送日志数据
	err = server.syncRunloop(session, nextseq)
	if err != nil {
		stdlog.Printf("[S %s] sync broken (%s)\n", remoteHost, err)
	}
	return
}
Ejemplo n.º 27
0
// ServerHandler.SessionOpened()
func (server *GoRedisServer) SessionOpened(session *Session) {
	server.counters.Get("connection").Incr(1)
	server.sessmgr.Put(session.RemoteAddr().String(), session)
	stdlog.Println("connection accepted from", session.RemoteAddr())
}
Ejemplo n.º 28
0
func (server *GoRedisServer) aofStart() (err error) {
	if server.aofwriter == nil {
		filename := server.opt.LogPath() + "/appendonly.aof"
		f, e := os.OpenFile(filename, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)
		if e != nil {
			return e
		}
		server.aofwriter = NewAOFWriter(bufio.NewWriter(f))
		defer func() {
			f.Close()
			server.aofwriter.Close()
			server.aofwriter = nil
		}()
		stdlog.Println("aof inited")
	}
	server.Suspend()
	snap := server.levelRedis.Snapshot()
	snapclosed := false // 避免关闭两次
	defer func() {
		if !snapclosed {
			snap.Close()
		}
	}()
	lastseq := server.synclog.MaxSeq()
	server.Resume()

	snap.KeyEnumerate([]byte(""), levelredis.IterForward, func(i int, key, keytype, value []byte, quit *bool) {
		// stdlog.Println(i, string(key), string(keytype))
		if server.aofwriter.IsClosed() {
			*quit = true
			return
		}
		switch string(keytype) {
		case "zset":
			server.aofwriter.AppendZSet(snap.GetSortedSet(string(key)))
		case "hash":
			server.aofwriter.AppendHash(snap.GetHash(string(key)))
		case "set":
			server.aofwriter.AppendSet(snap.GetSet(string(key)))
		case "list":
			server.aofwriter.AppendList(snap.GetList(string(key)))
		case "string":
			server.aofwriter.AppendString(key, value)
		case "doc":
			server.aofwriter.AppendDoc(snap.GetDoc(string(key)))
		case "none":
			stdlog.Println("bad key type", string(key), string(value))
		default:
			stdlog.Println("bad key type", string(key), string(keytype), string(value))
		}
	})

	snap.Close()
	snapclosed = true

	if server.aofwriter.IsClosed() {
		return errors.New("aof closed")
	}

	seq := lastseq + 1
	deplymsec := 10
	for {
		if server.aofwriter.IsClosed() {
			return errors.New("aof closed")
		}
		var val []byte
		val, err = server.synclog.Read(seq)
		if err != nil {
			stdlog.Printf("aof synclog read error %s\n", err)
			break
		}
		if val == nil {
			time.Sleep(time.Millisecond * time.Duration(deplymsec))
			deplymsec += 10
			if deplymsec >= 10000 {
				deplymsec = 10
			}
			continue
		} else {
			deplymsec = 10
		}

		server.aofwriter.Write(val)
		server.aofwriter.Flush()

		seq++
	}

	return nil
}
Ejemplo n.º 29
0
// ServerHandler.SessionClosed()
func (server *GoRedisServer) SessionClosed(session *Session, err error) {
	server.counters.Get("connection").Incr(-1)
	server.sessmgr.Remove(session.RemoteAddr().String())
	stdlog.Println("end connection", session.RemoteAddr(), err)
}
Ejemplo n.º 30
0
func (server *GoRedisServer) ExceptionCaught(err error) {
	stdlog.Printf("exception %s\n", err)
	stdlog.Println(string(debug.Stack()))
}