go/golang + redis 太多打开的文件错误

huangapple go评论117阅读模式
英文:

go/golang + redis too many open files error

问题

我正在使用Redis的Golang版本,并使用Redis官方推荐的Redigo连接器(https://github.com/garyburd/redigo)。

我已经做了以下操作:

  • 在每次Dial()之后使用defer Close()关闭连接。
  • 设置fs.file-max = 100000。
  • 设置vm.overcommit_memory = 1。
  • 禁用了保存操作。
  • 设置maxclients = 100000。

我运行的是一个高流量的网站,一切正常运行大约10分钟后,我遇到了以下错误:

error: dial tcp 127.0.0.1:6379: too many open files

然后我无法从我的应用程序中访问Redis。

我在Redis日志中没有看到任何错误或问题的提示。我该如何解决这个问题?

英文:

I'm using redis in Golang with the Redigo connector (https://github.com/garyburd/redigo) suggested by the Redis website.

I have:

  • After every Dial() I defer a Close()
  • Set fs.file-max = 100000
  • Set vm.overcommit_memory = 1
  • Disabled saving
  • Set maxclients = 100000

I run a high traffic website, and everything runs great for about 10 minutes, from which I get

error: dial tcp 127.0.0.1:6379: too many open files

Then I can't access redis at all from my application.

I see nothing in the redis logs to suggest any errors or problems. What do I do to fix this?

答案1

得分: 8

我不知道你使用的是哪个驱动程序,但是使用redigo,你可以在连接池中定义一定数量的打开连接,然后在每次对Redis的查询中,首先从连接池中获取一个客户端,然后关闭它,这样它就会返回到连接池并被重新使用,就像这样:

redisPool := &redis.Pool{
    MaxIdle:   3,
    MaxActive: 10, // 最大连接数
    Dial: func() (redis.Conn, error) {
        c, err := redis.Dial("tcp", ":6379")
        if err != nil {
            panic(err.Error())
        }
        return c, err
    },
}

r := redisPool.Get() // 从连接池中获取一个客户端
_, err = r.Do("GET one") // 使用客户端
if err != nil {
    panic(err.Error())
}

r.Close() // 关闭客户端,使连接得到重用
英文:

I don't know which driver you use but with redigo you can define a number of open connections in a pool, all you have to do then is in every query to redis, first get a client from the pool, then close it, so it goes back to the pool and gets re-used, just like this:

redisPool = &redis.Pool{
        MaxIdle: 3,
        MaxActive: 10, // max number of connections
        Dial: func() (redis.Conn, error) {
                c, err := redis.Dial("tcp", ":6379")
                if err != nil {
                        panic(err.Error())
                }
                return c, err
        },
}
r := redisPool.Get() // get a client from the pool
_, err = r.Do("GET one") // use the client
if err != nil {
        panic(err.Error())
}
r.Close() // close the client so the connection gets reused

答案2

得分: 5

你的问题是Redis无法打开新连接,然后变得无响应,你需要增加操作系统的文件描述符限制(Ubuntu默认为1024,可能会有问题),这目前占据了Redis的maxclients设置。

调整这个限制的方式取决于Redis运行的操作系统,在Linux上,你需要执行类似以下命令:

ulimit -n 99999
英文:

Your problem is that Redis cant open new connections and then becomes unresponsive, you need to increase the file descriptors limit of your operating system (ubuntu defaults to 1024 which can be a problem) which right now is dominating the redis maxclients setting.

The way you tweak this limit depends on the os redis is running, on linux you need something like this:

ulimit -n 99999

huangapple
  • 本文由 发表于 2013年11月14日 15:29:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/19971968.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定