我有一個應用程序,每秒鐘約400次讀取和每秒100次寫入redis(託管在redislabs上)。該應用程序使用github.com/garyburd/redigo
包作爲redis代理。redigo:獲得撥號tcp:連接:不能分配請求的地址
我有兩個功能,這是正在使用的唯一的讀寫:
func getCachedVPAIDConfig(key string) chan *cachedVPAIDConfig {
c := make(chan *cachedVPAIDConfig)
go func() {
p := pool.Get()
defer p.Close()
switch p.Err() {
case nil:
item, err := redis.Bytes(p.Do("GET", key))
if err != nil {
c <- &cachedVPAIDConfig{nil, err}
return
}
c <- &cachedVPAIDConfig{item, nil}
default:
c <- &cachedVPAIDConfig{nil, p.Err()}
return
}
}()
return c
}
func setCachedVPAIDConfig(key string, j []byte) chan error {
c := make(chan error)
go func() {
p := pool.Get()
defer p.Close()
switch p.Err() {
case nil:
_, err := p.Do("SET", key, j)
if err != nil {
c <- err
return
}
c <- nil
default:
c <- p.Err()
return
}
}()
return c
}
正如你所看到的,我使用推薦的連接池機制(http://godoc.org/github.com/garyburd/redigo/redis#Pool)。
我在每個http請求上調用應用程序上的端點上的這些函數。問題是:一旦應用程序開始變得請求時,它立即開始引發錯誤
dial tcp 54.160.xxx.xx:yyyy: connect: cannot assign requested address
(54.160.xxx.xx:yyyy是Redis的主機)
我對Redis的看到,只有大約600個連接,當這開始發生時,聽起來不是很多。
我試着玩pool
的MaxActive
設置,設置在1000到50K之間的任何地方,但結果是一樣的。
任何想法?
編輯
這裏是我的游泳池初始化代碼(在func init
這樣做):
pool = redis.Pool{
MaxActive: 1000, // note: I tried changing this to 50K, result the same
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", redisHost)
if err != nil {
return nil, err
}
if _, err := c.Do("AUTH", redisPassword); err != nil {
c.Close()
return nil, err
}
return c, err
},
}
編輯2:通過應用的東西解決 問題在下面的答案建議!
爲池初始化新代碼:
pool = redis.Pool{
MaxActive: 500,
MaxIdle: 500,
IdleTimeout: 5 * time.Second,
Dial: func() (redis.Conn, error) {
c, err := redis.DialTimeout("tcp", redisHost, 100*time.Millisecond, 100*time.Millisecond, 100*time.Millisecond)
if err != nil {
return nil, err
}
if _, err := c.Do("AUTH", redisPassword); err != nil {
c.Close()
return nil, err
}
return c, err
},
}
這個新的init使得它,以便獲取和設置超時由redigo內部處理的,所以我不再需要返回的getCachedVPAIDConfig和setCachedVPAIDConfig funcs中通道。這是他們現在的樣子:
func setCachedVPAIDConfig(key string, j []byte) error {
p := pool.Get()
switch p.Err() {
case nil:
_, err := p.Do("SET", key, j)
p.Close()
return err
default:
p.Close()
return p.Err()
}
}
func getCachedVPAIDConfig(key string) ([]byte, error) {
p := pool.Get()
switch p.Err() {
case nil:
item, err := redis.Bytes(p.Do("GET", key))
p.Close()
return item, err
default:
p.Close()
return nil, p.Err()
}
}
請附上池初始化代碼。 –
@Not_a_Golfer完成 – orcaman