iT邦幫忙

2024 iThome 鐵人賽

DAY 21
0
Odoo

Odoo 部署策略系列 第 21

odoo.conf 效能調整實驗:多行程與資料庫連線設定

  • 分享至 

  • xImage
  •  

在上一篇文章中,我們了解了 odoo 的多行程設定和效能改善的理論基礎。在這一章中,我將透過實際的實驗,調整 odoo.conf 中的多行程與資料庫連線設定,並觀察對系統效能的影響。


實驗環境

我使用 Siege 進行壓力測試,模擬多個使用者同時訪問 odoo 系統的情況。我不是這方面的專家,所以這只是一個非常粗糙的測試方式。測試指令如下:

siege -c [並發使用者數] -t 1M https://odoo-dev.internal.example.local
  • -c:指定並發的使用者數量。
  • -t:測試持續時間,這裡設為 1 分鐘。

我這次的測試統一都讓它跑滿一分鐘,讓資料更好進行比較。有一些測試因為失敗率太高,會被強制中止,可以在 Siege 的設定裡把預設的 1024 次失敗跳出調高,讓測試可以跑完。

cat ~/.siege/siege.conf | grep failure -A 4 -B 4
#
# Failures: This is the number of total connection failures allowed
# before siege aborts. Connection failures (timeouts, socket failures,
# etc.) are combined with 400 and 500 level errors in the final stats,
# but those errors do not count against the abort total.  If you set
# this total to 10, then siege will abort after ten socket timeouts,
# but it will NOT abort after ten 404s. This is designed to prevent a
# run-away mess on an unattended siege.
#
# The default value is 1024
#
# ex: failures = 50
#
failures = 1048576

1. 未修改任何設定的狀態

1.1 60 個使用者測試

首先,在未修改任何設定的情況下,我以 60 個並發使用者進行測試,結果如下:

{       "transactions":                        20033,
        "availability":                        99.94,
        "elapsed_time":                        59.25,
        "data_transferred":                  1219.25,
        "response_time":                        0.18,
        "transaction_rate":                   338.11,
        "throughput":                          20.58,
        "concurrency":                         59.82,
        "successful_transactions":             20045,
        "failed_transactions":                    12,
        "longest_transaction":                  0.46,
        "shortest_transaction":                 0.00
}

另外在測試時,我也進入容器中使用 top 觀察系統資源的利用狀況。
https://ithelp.ithome.com.tw/upload/images/20241005/20168935btADcoTzc3.png

分析:

  • 可用性(availability) 高達 99.94%,只有少數失敗的交易。
  • 系統在 60 個並發使用者下運行正常。
  • transaction_rate 大約為 300 左右。
  • 系統資源觀察到只有一個 python3 的行程,並且 CPU 使用率高達 120%,但符合預期。

1.2 100 個使用者測試

接下來,我將並發使用者數增加到 100 個

{
    "transactions":              17687,
    "availability":              91.22,
    "elapsed_time":              59.66,
    "data_transferred":          1009.77,
    "response_time":             0.34,
    "transaction_rate":          296.46,
    "throughput":                16.93,
    "concurrency":               99.49,
    "successful_transactions":   19669,
    "failed_transactions":       1702,
    "longest_transaction":       0.84,
    "shortest_transaction":      0.00
}

分析:

  • 可用性 下降到 91.22%,出現了 1702 筆失敗的交易
  • 顯示系統在 100 個並發使用者下出現瓶頸。
  • 在 odoo 的 log 中,我多次發現了以下錯誤訊息:psycopg2.pool.PoolError: The Connection Pool Is Full,這表示 odoo 連線到資料庫的連線池已滿,無法處理更多連線。

2. 調整 odoo 的資料庫連線設定至 128

為了解決連線池已滿的問題,我查看 odoo.confdb_maxconn 設定,發現其預設值為 64,剛好可以容納我們 60 人的測試。於是我嘗試在 odoo.conf 中將 db_maxconn 從預設值增加到 128

調整後的設定

db_maxconn = 128

2.1 100 個使用者測試

再次以 100 個並發使用者進行測試。

{
    "transactions":              500,
    "availability":              8.04,
    "elapsed_time":              59.38,
    "data_transferred":          1.24,
    "response_time":             11.78,
    "transaction_rate":          8.42,
    "throughput":                0.02,
    "concurrency":               99.23,
    "successful_transactions":   1026,
    "failed_transactions":       5717,
    "longest_transaction":       1.02,
    "shortest_transaction":      0.00
}

分析:

  • 可用性 驟降至 8.04%,失敗的交易數量達到 5717
  • 系統效能不僅沒有改善,反而更差。
  • 觀察之後,這次錯誤出現在 PostgreSQL 的日誌中,大量出現以下訊息:FATAL: sorry, too many clients already,也就是說,雖然我在 odoo 中將連線數設定變大了,但是資料庫那邊無法處理這麼多的連線。

3. 根據資料庫設定調整 odoo 的連線數設定

意識到問題出在資料庫那邊後,我檢查了 PostgreSQL 的設定:

root@0abc279cce9b:/# cat /var/lib/postgresql/data/postgresql.conf | grep max_connections
max_connections = 100

發現資料庫預設的最大連線數為 100,而我在 odoo 中將 db_maxconn 設為 128,導致超過資料庫的負荷,而無法服務的資料庫反而造成 odoo 更多的問題,最終導致效能驟降。
於是我嘗試將 odoo 的 db_maxconn 往回調整成 100 ,配合資料庫的設定。

調整後的設定

db_maxconn = 100

3.1 100 個使用者測試

再次進行測試。

{
    "transactions":              305,
    "availability":              5.09,
    "elapsed_time":              59.63,
    "data_transferred":          1.16,
    "response_time":             19.39,
    "transaction_rate":          5.11,
    "throughput":                0.02,
    "concurrency":               99.16,
    "successful_transactions":   861,
    "failed_transactions":       5687,
    "longest_transaction":       2.01,
    "shortest_transaction":      0.00
}

分析:

  • 可用性 仍然很低,只有 5.09%。
  • 系統效能未見改善。
  • 這次我就想不通是為什麼,後來是我發現到我的瀏覽器還開著幾個分頁沒關掉,推測可能是這樣佔用了連線數量,導致超過最大連線數。

3.2 關閉瀏覽器後重新測試

於是我關閉了瀏覽器的分頁後,再次進行測試。

{
    "transactions":              19090,
    "availability":              99.80,
    "elapsed_time":              59.44,
    "data_transferred":          1156.29,
    "response_time":             0.31,
    "transaction_rate":          321.16,
    "throughput":                19.45,
    "concurrency":               99.53,
    "successful_transactions":   19116,
    "failed_transactions":       38,
    "longest_transaction":       0.85,
    "shortest_transaction":      0.00
}

分析:

  • 可用性 提升至 99.80%,系統效能恢復正常。
  • 顯示瀏覽器的連線可能影響了測試結果。

3.3 105 個使用者測試

為了驗證問題是否是因為超過了 100 的上限,我再次進行測試,增加並發使用者數到 105 個

{
    "transactions":              18496,
    "availability":              99.69,
    "elapsed_time":              59.19,
    "data_transferred":          1138.82,
    "response_time":             0.33,
    "transaction_rate":          312.49,
    "throughput":                19.24,
    "concurrency":               104.62,
    "successful_transactions":   18736,
    "failed_transactions":       57,
    "longest_transaction":       0.93,
    "shortest_transaction":      0.00
}

測試的結果表明超過上限不是問題,於是我又把瀏覽器的分頁打開並進行測試,但還是無法復現之前的問題,這有點奇怪,但我決定先不理會了。


4. 調整為多行程模式

為了進一步提升效能,我決定將 odoo 的運行模式從多執行緒(Multi-Thread)改為 多行程(Multi-Process),調整了一些設定。

修改 odoo.conf 設定

workers = 10
max_cron_threads = 2
limit_memory_hard = 2684354560
limit_memory_soft = 2147483648
limit_request = 8192
limit_time_cpu = 60
limit_time_real = 120
  • workers = 10:設定 10 個工作行程。
  • max_cron_threads = 2:設定 2 個 cron 行程。
  • 其他參數調整了記憶體限制和時間限制,我是隨便抓的數字,並不太準確。

4.1 100 個使用者測試

進行 100 個並發使用者的測試。

{
    "transactions":              106175,
    "availability":              99.85,
    "elapsed_time":              59.48,
    "data_transferred":          6530.79,
    "response_time":             0.06,
    "transaction_rate":          1785.05,
    "throughput":                109.80,
    "concurrency":               99.58,
    "successful_transactions":   106372,
    "failed_transactions":       160,
    "longest_transaction":       1.26,
    "shortest_transaction":      0.00
}

並且同時進入容器中觀察系統資源使用狀況:
https://ithelp.ithome.com.tw/upload/images/20241005/20168935gFwQz2d55h.png

分析:

  • 可用性 維持在 99.85%。
  • transaction_rate 從原本的平均 300 左右,大幅提升至 1785.05,效能有顯著改善。
  • 平均響應時間 降至 0.06 秒,系統反應更迅速。
  • top 顯示我們這次有 14 個 python3 行程,雖然跟設定的好像不太一樣,但仔細觀察看起來 CPU 占用率較高的是 10 個,應該是對應 worker 的數量,剩下的可能就是 cron 之類的連線。

實驗總結

  1. 資料庫連線設定需在 odoo 端和資料庫端匹配:調整 odoo 的 db_maxconn 時,需考慮資料庫的 max_connections 設定,避免超過資料庫的負荷。

  2. 環境因素可能影響測試結果:測試時應確保沒有其他佔用連線的應用程式,例如關閉不必要的瀏覽器分頁,以免影響測試準確性。

  3. 多行程模式顯著提升效能:雖然我切換到 Multi-Process 模式並開了 10 個 worker,效能卻只提升了五倍多,但這可能是因為我 host 系統的資源已經吃滿了,導致效能無法再往上,可以看到下圖我的本機 CPU 使用率全部達到 100%,這在 Multi-Thread 模式下是達不到的,不管怎麼催,都會有 CPU 在發呆。這證明了如果使用 Multi-Process 可以解放更多硬體該有的效能,而不會被軟體設計限制,是生產環境中推薦的設定。

https://ithelp.ithome.com.tw/upload/images/20241005/20168935ZJstGBojuO.png


下一篇,我們將來探討如何透過已經設定好的 Multi-Process 模式,結合 Nginx 反向代理設定,讓 odoo 的實時系統正常運作。


上一篇
提升效能:odoo.conf 的多行程伺服器設定介紹
下一篇
odoo LiveChat 實時更新:使用 Nginx 反向代理處理 WebSocket
系列文
Odoo 部署策略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言