100萬個資料庫連接配接,絕逼瘋了,常人怎麼會幹這種事情。
沒錯,資料庫支援100萬個連接配接意味着什麼呢?不能用連接配接池嗎?
除了抱着玩一玩的心态,也能了解到作業系統層的一些知識,何樂不為?
根據我前幾天寫的《如何度量kernel resources for postgresql》,我們可以評估得出,如果要支援100萬個資料庫用戶端連接配接,作業系統應該如何配置。
<a href="https://yq.aliyun.com/articles/58690">https://yq.aliyun.com/articles/58690</a>
但是實際上能如願嗎?
以postgresql 9.5為例,100萬個連接配接,需要多少信号量?
需要多少組信号量?
100萬連接配接,semmni >= 62500
需要多少信号量?
100萬連接配接,semmns >= 1062500
每組需要多少信号量?
測試環境如下
centos 6.x x64, 512gb記憶體。
以上核心配置,信号量完全滿足100萬連接配接需求。
那麼資料庫能啟動嗎?
啟動失敗。
報錯來自如下代碼:
使用semget建立sem失敗。
src/backend/port/sysv_sema.c
semget之是以失敗,并不是kernel.sem的配置問題,而是作業系統核心的宏限制。
sem的分組數量不能大于semvmx,也就是說,最多能開50多萬個連接配接。
如下
kernels/xxx.x86_64/include/uapi/linux/sem.h
超過32767個array後會報錯
使用ipcs -l也能檢視到目前值
這個值隻能重新編譯核心來修改。
在semctl和semop的手冊中也能看到,有此說法。
100萬連接配接沒戲了嗎?
當然可以辦到。
例如修改semvmx,并重新編譯核心顯然是一條路,但是還有其他路子嗎?
我們前面看到,報錯的代碼是
internalipcsemaphorecreate@src/backend/port/sysv_sema.c
檢視對應頭檔案,發現pg支援幾種建立信号量的方式,真的是柳暗花明又一春 :
sysv, posix(named , unamed), win32
對應的頭檔案源碼如下
src/include/storage/pg_sema.h
其中posix的named和unamed分别使用如下系統調用
posix named 方式建立信号 :
posix unamed 方式建立信号 :
posix源碼如下,注意用到的宏
src/backend/port/posix_sema.c
從src/include/storage/pg_sema.h 可以看到,在pg_config.h中必須有一個指定的use_xxx_semaphores symbols。
這個symbol不是直接設定pg_config.h來的,是在configure時設定的,會自動加到pg_config.h 。
預設使用sysv,如果要使用其他的sem方法。
可以這麼做
記得加-lpthread ,否則報錯
通過這些系統調用的linux程式設計幫助文檔,了解一下posix的信号量管理
可以得知sem_open 也受到semvmx的限制
是以為了在不修改核心的情況下,實作postgresql支援100萬個連接配接,甚至更多。
必須使用use_unnamed_posix_semaphores
使用use_unnamed_posix_semaphores編譯
修改參數,允許100萬個連接配接
重新開機資料庫
pgbench是很好的測試工具,隻不過限制了1024個連接配接,為了支援100萬個連接配接測試,需要修改一下。
代碼
測試表
測試腳本
開始壓測,遇到第一個問題
這個問題還好,是打開檔案數受限,改一些限制就可以解決
修改ulimit
修改核心參數
重測,再次遇到問題,原因是pgbench使用了ip位址連接配接pg,導緻pgbench的動态端口耗盡。
換成unix socket連接配接即可解決。
不能fork new process,後面跟了個cannot allocate memory這樣的提示,我看了目前的配置
于是我加了交換分區,同時改了幾個參數
重新測試,發現還是有問題
使用以下手段觀測,發現在約連接配接到 65535 時報錯
找到了根源,是核心限制了
修改一下這個核心參數
重新測試
繼續觀測
連接配接到26萬時,記憶體用了約330gb,每個連接配接1mb左右。
看起來應該沒有問題了,隻要記憶體足夠是可以搞定100萬連接配接的。
為了讓postgresql支援100萬個并發連接配接,除了資源(主要是記憶體)要給足。
資料庫本身編譯也需要注意,還需要作業系統核心也需要一些調整。
編譯postgresql 時使用 posix unname sem 。
如果你不打算使用unnamed posix sem,那麼務必重新編譯作業系統核心,增加semvmx.
打開檔案數限制
ulimit
使用unix socket
突破pgbench測試時,動态端口數量限制。
每個連接配接約1mb,100萬個連接配接,需要約1tb記憶體,需要給足記憶體。
啟用swap
實際上還是發生了oom,而且hang了很久。
最大pid值的限制
加大
pgbench用戶端的限制
修改源碼,支援無限連接配接。
ipcs不統計posix sem的資訊,是以使用posix sem後ipcs看不到用了多少sem.
system v 與 posix sem
《dba不可不知的作業系統核心參數》
<a href="https://yq.aliyun.com/articles/58751">https://yq.aliyun.com/articles/58751</a>
《如何度量kernel resources for postgresql》
祝大家玩得開心,歡迎随時來 阿裡雲促膝長談業務需求 ,恭候光臨。
阿裡雲的小夥伴們加油,努力 做好核心與服務,打造最貼地氣的雲資料庫 。