去 Redis 加载
Go Redis Loading
我正在尝试将 2 亿个密钥加载到 redis 中,通常在大约 3100 万个密钥时开始出现错误,并且必须 stop.I 我正在使用 golang 和 redis 库 "github.com/garyburd/redigo/redis"
我是这样设置连接池的:
func newPool(server string) *redis.Pool {
return &redis.Pool{
MaxIdle: 3,
MaxActive: 10,
IdleTimeout: 240 * time.Second,
Dial: func () (redis.Conn, error) {
c, err := redis.Dial("tcp", server)
if err != nil {
return nil, err
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
}
然后我尝试用这个函数的值填充redis:
func RedisServerBatchLoadKeys(rtbExchange string, keys []string){
redisLock.Lock()
defer redisLock.Unlock()
retry := 0
for {
conn := GetConnOrPanic(rtbExchange)
defer conn.Close()
conn.Send("MULTI")
for _, key := range keys {
conn.Send("SET", key, maxCount)
conn.Send("EXPIRE", key, numSecondsExpire)
}
_, err := conn.Do("EXEC")
if err == nil {
break
} else if !(err == io.EOF) {
CheckRedisError(err, rtbExchange, "Could not load batch")
} else {
retry ++
}
if retry >= 10 {
CheckRedisError(err, rtbExchange, "Could not load batch - 10 retries")
}
}
}
我遇到了很多错误,例如:
- 读取 tcp 10.249.15.194:6379:连接被对等方重置
- 拨打 tcp 10.249.15.194:6379: 连接被拒绝
- redis#RedisError : EOF
我是在做一些根本性的错误还是我必须添加更多的错误检查(除了我添加的 EOF)。
谢谢,
只是一个猜测:2 亿个密钥很多。你有足够的内存来容纳那个大小的数据库吗?
Redis 文档说:
Redis can handle up to 2^32 keys, and was tested in practice to handle at least 250 million of keys per instance.
In other words your limit is likely the available memory in your system.
他们还说:
What happens if Redis runs out of memory?
Redis will either be killed by the Linux kernel OOM killer, crash with an error, or will start to slow down.
我认为您无法连接似乎是合理的,因为服务器实际上已关闭。也许它会重新启动,下次你 运行 你的脚本时,它每次都会到达同一个地方,因为那是你 运行 内存不足的时候。
如果这是您的问题,您可以尝试以下几种方法:
- 使用redis哈希可以更有效地存储数据。参见 http://redis.io/topics/memory-optimization
- 将您的数据集分区(分片)到多个服务器(例如,如果您有 4 个服务器,您可以使用
key % 4
来确定要存储在哪个 redis 服务器下)如果您想要的是 O (1) 查找你仍然会得到它,虽然你已经让你的系统更脆弱,因为有多个故障点。
我正在尝试将 2 亿个密钥加载到 redis 中,通常在大约 3100 万个密钥时开始出现错误,并且必须 stop.I 我正在使用 golang 和 redis 库 "github.com/garyburd/redigo/redis"
我是这样设置连接池的:
func newPool(server string) *redis.Pool {
return &redis.Pool{
MaxIdle: 3,
MaxActive: 10,
IdleTimeout: 240 * time.Second,
Dial: func () (redis.Conn, error) {
c, err := redis.Dial("tcp", server)
if err != nil {
return nil, err
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
}
然后我尝试用这个函数的值填充redis:
func RedisServerBatchLoadKeys(rtbExchange string, keys []string){
redisLock.Lock()
defer redisLock.Unlock()
retry := 0
for {
conn := GetConnOrPanic(rtbExchange)
defer conn.Close()
conn.Send("MULTI")
for _, key := range keys {
conn.Send("SET", key, maxCount)
conn.Send("EXPIRE", key, numSecondsExpire)
}
_, err := conn.Do("EXEC")
if err == nil {
break
} else if !(err == io.EOF) {
CheckRedisError(err, rtbExchange, "Could not load batch")
} else {
retry ++
}
if retry >= 10 {
CheckRedisError(err, rtbExchange, "Could not load batch - 10 retries")
}
}
}
我遇到了很多错误,例如:
- 读取 tcp 10.249.15.194:6379:连接被对等方重置
- 拨打 tcp 10.249.15.194:6379: 连接被拒绝
- redis#RedisError : EOF
我是在做一些根本性的错误还是我必须添加更多的错误检查(除了我添加的 EOF)。
谢谢,
只是一个猜测:2 亿个密钥很多。你有足够的内存来容纳那个大小的数据库吗?
Redis 文档说:
Redis can handle up to 2^32 keys, and was tested in practice to handle at least 250 million of keys per instance.
In other words your limit is likely the available memory in your system.
他们还说:
What happens if Redis runs out of memory?
Redis will either be killed by the Linux kernel OOM killer, crash with an error, or will start to slow down.
我认为您无法连接似乎是合理的,因为服务器实际上已关闭。也许它会重新启动,下次你 运行 你的脚本时,它每次都会到达同一个地方,因为那是你 运行 内存不足的时候。
如果这是您的问题,您可以尝试以下几种方法:
- 使用redis哈希可以更有效地存储数据。参见 http://redis.io/topics/memory-optimization
- 将您的数据集分区(分片)到多个服务器(例如,如果您有 4 个服务器,您可以使用
key % 4
来确定要存储在哪个 redis 服务器下)如果您想要的是 O (1) 查找你仍然会得到它,虽然你已经让你的系统更脆弱,因为有多个故障点。