我是靠谱客的博主 深情凉面,最近开发中收集的这篇文章主要介绍Postgresql中TCP keepalive相关设置使用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

数据库连接描述

提起TCP keepalive相关的设置,就避不开数据库连接这个话题,目前大部分使用环境,数据库连接都是长连接,也就是说连接可以复用。

由于数据库建立连接和HTTP连接还不一样,HTTP是无状态的,新建连接的代价比较小,但是数据库建立连接代价高多了,因为数据库连接不是无状态的;比如,在关闭连接的情况下,将会丢失打开的事务、临时表和prepare语句。而且连接进程都是由postgres主进程fork,fork也有相应的代价,所以数据库有一些空闲会话是正常的,但是保持太长时间大量的空闲会话也是不好的。

14版本引入了idle_session_timeout参数,可以在设置该参数,超过设置的时间,数据库会关闭空闲连接。之前的老版本可以使用pg_timeout插件,达到同样的效果。但是同样也会关闭掉我们想保留的正常的空闲连接,所以设置TCP keepalive是更好的解决方案。

TCP keepalive是什么?

Keepalive是TCP协议的一种功能配置。当在TCP网络套接字上设置SO_KEEPALIVE选项时,计时器将在套接字空闲时开始运行。当超过keepalive空闲时间,socket没有进一步的活动时,内核将向client发送一个“keepalive packet”。如果client应答,则认为连接良好,计时器再次开始运行。

如果没有应答,内核在发送另一个keepalive包之前会等待keepalive间隔时间。重复这个过程,直到发送keepalive报文的数量达到keepalive计数。在那之后,连接被认为已失效,尝试使用网络套接字将导致错误。

注意,发送keepalive消息的是操作系统内核,而不是应用程序(数据库server或client)。应用程序不知道这个过程。

keepalive有两个目的:

  1. 保持网络不空闲,如上,间隔性的发送keepalive packet
  2. 检测另一个通信端是否已经断开,比如断电导致的异常连接失效,通过该设置,可以关闭网络连接。

系统和数据库相关参数设置

操作系统内核参数:

tcp_keepalive_intvl (integer; default: 75; since Linux 2.4)
       The number of seconds between TCP keep-alive probes.

tcp_keepalive_probes (integer; default: 9; since Linux 2.2)
       The  maximum  number  of  TCP  keep-alive  probes  to send before giving up and killing the connection if no
       response is obtained from the other end.

tcp_keepalive_time (integer; default: 7200; since Linux 2.2)
       The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes.   Keep-
       alives  are  sent only when the SO_KEEPALIVE socket option is enabled.  The default value is 7200 seconds (2
       hours).  An idle connection is terminated after approximately an additional 11 minutes (9 probes an interval
       of 75 seconds apart) when keep-alive is enabled.

参数可以在/proc/sys/net/ipv4下找到

#编程时三个参数和以上三个参数的关系对应
TCP_KEEPCNT(keepalive计数,连续发送探测包后,达到该计数设置并没有回应,则认为连接已失效) 覆盖  tcp_keepalive_probes,默认9(次)
TCP_KEEPIDLE(keepalive空闲时间,超过该设置,发送packet) 覆盖 tcp_keepalive_time,默认7200(秒)
TCP_KEEPINTVL(keepalive间隔时间,发送packet后,没有回应,等待该间隔时间后再次发送) 覆盖 tcp_keepalive_intvl,默认75(秒)
# 查询
cat /proc/sys/net/ipv4/tcp_keepalive_time  
或
sysctl net.ipv4.tcp_keepalive_time
#修改
sysctl net.ipv4.tcp_keepalive_time=3600
或修改/etc/sysctl.conf文件

知道了以上介绍,那么我们看下postgresql数据库的参数设置

# see "man 7 tcp" for details

tcp_keepalives_idle = 60                # TCP_KEEPIDLE, in seconds;
                                        # 0 selects the system default
tcp_keepalives_interval = 20            # TCP_KEEPINTVL, in seconds;
                                        # 0 selects the system default
tcp_keepalives_count = 10               # TCP_KEEPCNT;
                                        # 0 selects the system default

如果都设置为0,那么将使用系统内核参数的设置。很明显,我们使用系统默认的设置,检测无效连接的时间太长了,所以我需要设置数据库层面的参数,以更短时间检测出无效连接。

以下是我的设置,这样可以在5分钟以内就探测出无效连接

tcp_keepalives_idle = 60                # TCP_KEEPIDLE, in seconds;
tcp_keepalives_interval = 20            # TCP_KEEPINTVL, in seconds;
tcp_keepalives_count = 10               # TCP_KEEPCNT;

另外PG14版本还引入了client_connection_check_interval参数,每隔一段时间检测client是否离线,如果已经离线,则快速结束掉正在运行的query,防止连接已经失效了,但是还在执行查询返回给客户端,浪费数据库资源。默认是0,单位默认毫秒。

参考:
https://www.cybertec-postgresql.com/en/tcp-keepalive-for-a-better-postgresql-experience/
https://www.postgresql.org/docs/14/runtime-config-connection.html

最后

以上就是深情凉面为你收集整理的Postgresql中TCP keepalive相关设置使用的全部内容,希望文章能够帮你解决Postgresql中TCP keepalive相关设置使用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部