Redis如何處理客戶端連接

Redis處理客戶端連接的過程如下:


Redis accepts clients connections on the configured listening TCP port and on the Unix socket if enabled. When a new client connection is accepted the following operations are performed:


1.The client socket is put in non-blocking state since Redis uses multiplexing and non-blocking I/O.

2.The TCP_NODELAY option is set in order to ensure that we don't have delays in our connection.

3.A readable file event is created so that Redis is able to collect the client queries as soon as new data is available to be read on the socket.


在客戶端初始化後,Redis會檢查是否達到最大連接數,若達到了,其會返回客戶端一個報錯,隨後關閉連接。


對於maxclients參數,配置中默認爲10000。


# Set the max number of connected clients at the same time. By default

# this limit is set to 10000 clients, however if the Redis server is not

# able to configure the process file limit to allow for the specified limit

# the max number of allowed clients is set to the current file limit

# minus 32 (as Redis reserves a few file descriptors for internal uses).

#

# Once the limit is reached Redis will close all the new connections sending

# an error 'max number of clients reached'.

#

# maxclients 10000



某天收到一個報警,說是連接數不多了,通過client list查看發現連接中有很多idle很大的連接。


id=6665171818 addr=192.168.4.66:56207 fd=374 name= age=172130 idle=172085 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=hmget

id=6576394514 addr=192.168.6.121:43269 fd=545 name= age=378277 idle=84307 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=expire

id=6702222993 addr=192.168.7.147:33843 fd=990 name= age=74926 idle=64641 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=hgetall


其實這些連接都早已不是活躍連接了,Redis提供了一個timeout參數處理這種情況,該參數默認沒有開啓。


# Close the connection after a client is idle for N seconds (0 to disable)

timeout 0


從最佳實踐的角度建議還是開啓,如timeout 1800(上述實例設置後,連接釋放了很多)。文檔也提到開啓timeout,可預防兩種情況:


1.Mission critical applications where a bug in the client software may saturate the Redis server with idle connections, causing service disruption.


2.As a debugging mechanism in order to be able to connect with the server if a bug in the client software saturates the server with idle connections, making it impossible to interact with the server.


該參數設置的時間並不是精確的,Redis這樣也是爲了性能的考慮。


Timeouts are not to be considered very precise: Redis avoids to set timer events or to run O(N) algorithms in order to check idle clients, so the check is performed incrementally from time to time. This means that it is possible that while the timeout is set to 10 seconds, the client connection will be closed, for instance, after 12 seconds if many clients are connected at the same time.



同timeout類似,還有一個tcp-keepalive參數,也是斷掉異常連接作用,該參數是默認開啓的。


# TCP keepalive.

#

# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence

# of communication. This is useful for two reasons:

#

# 1) Detect dead peers.

# 2) Take the connection alive from the point of view of network

#    equipment in the middle.

#

# On Linux, the specified value (in seconds) is the period used to send ACKs.

# Note that to close the connection the double of the time is needed.

# On other kernels the period depends on the kernel configuration.

#

# A reasonable value for this option is 300 seconds, which is the new

# Redis default starting with Redis 3.2.1.

tcp-keepalive 300


要想從機制上闡述這兩個參數作用,又要進入到源碼了,再一次說明代碼是最直接的生產力。



Redis在處理客戶端連接時,還會考慮輸入、輸出緩衝的限制,可查看“CLIENT LIST中qbuf,qbuf-free和obl,oll,omem的含義”。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章