Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 转到Redis加载_Go_Redis - Fatal编程技术网

Go 转到Redis加载

Go 转到Redis加载,go,redis,Go,Redis,我正在尝试将2亿个密钥加载到redis中,通常会在3100万个密钥左右出现错误,因此必须停止。我正在使用golang和redis库“github.com/garyburd/redigo/redis” 我设置了一个连接池,如下所示: func newPool(server string) *redis.Pool { return &redis.Pool{ MaxIdle: 3, MaxActive: 10, IdleTimeout:

我正在尝试将2亿个密钥加载到redis中,通常会在3100万个密钥左右出现错误,因此必须停止。我正在使用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最多可以处理2^32个密钥,并且在实践中经过测试,每个实例至少可以处理2.5亿个密钥

换句话说,您的限制可能是系统中的可用内存

他们还说:

如果Redis内存不足怎么办

Redis要么被Linux内核OOM杀手杀死,要么因错误而崩溃,要么开始减速

在我看来,您无法连接似乎是合理的,因为服务器实际上已关闭。也许它会重新启动,下次运行脚本时,它每次都会到达相同的位置,因为此时内存不足

如果这是您的问题,您可以尝试以下几点:

  • 使用redis散列可以更有效地存储数据。看
  • 在多台服务器上对数据集进行分区(shard)(例如,如果您有4台服务器,您可以使用
    键%4
    来确定要在哪个redis服务器下存储),如果您要进行的是O(1)查找,您仍然会得到该结果,尽管由于存在多个故障点,您的系统变得更加脆弱

  • 我不知道
    GetConnOrPanic()
    做什么,但您是否正在尝试在一个事务中设置数百万个值?将每个SET/EXPIRE放在一个MULTI/EXEC事务中。对不起,我一次将它们设置为100。似乎您在每次迭代中都从池中获得了一个新连接,而没有关闭它。延迟只在函数退出时关闭它。我建议删除外部重试循环。如果应用程序无法设置这些键,则说明出现了问题。重试可能会掩盖此问题。使用SETEX可以使用单个命令设置密钥和过期时间。检查您在单个事务中设置的密钥数。在事务中设置一百万个密钥将失败。你能给我看一下GetConnOrPanic的代码或者解释一下它的功能吗?我最终发现redis服务器上的内存已经用完了。谢谢你的帮助。将移动到redis哈希。