連線池
查詢引擎管理資料庫連線的連線池。連線池在 Prisma Client 開啟與資料庫的第一個連線時建立,這可能透過以下兩種方式之一發生
- 透過明確呼叫
$connect()
或 - 透過執行第一個查詢,這會在底層呼叫
$connect()
關聯式資料庫連接器使用 Prisma ORM 自己的連線池,而 MongoDB 連接器使用MongoDB 驅動程式連線池。
關聯式資料庫
關聯式資料庫連接器使用 Prisma ORM 的連線池。連線池具有連線限制和連線池逾時,這些都由連線網址參數控制。
連線池運作方式
以下步驟描述查詢引擎如何使用連線池
- 查詢引擎實例化一個連線池,其中包含可配置的池大小和池逾時。
- 查詢引擎建立一個連線並將其新增到連線池。
- 當查詢進入時,查詢引擎會從池中保留一個連線以處理查詢。
- 如果連線池中沒有閒置連線可用,查詢引擎會開啟額外的資料庫連線並將其新增到連線池,直到資料庫連線數量達到
connection_limit
定義的限制。 - 如果查詢引擎無法從池中保留連線,則查詢會新增到記憶體中的 FIFO(先進先出)佇列。FIFO 表示查詢會按照它們進入佇列的順序處理。
- 如果查詢引擎無法在時間限制之前處理佇列中的查詢,它會為該查詢拋出錯誤代碼
P2024
的例外,然後繼續處理佇列中的下一個查詢。
如果您持續遇到池逾時錯誤,您需要最佳化連線池。
連線池大小
預設連線池大小
連線的預設數量(池大小)使用以下公式計算
num_physical_cpus * 2 + 1
num_physical_cpus
代表您的應用程式執行的機器上的實體 CPU 數量。如果您的機器有四個實體 CPU,您的連線池將包含九個連線(4 * 2 + 1 = 9
)。
雖然該公式代表一個良好的起點,但建議的連線限制也取決於您的部署範例 - 特別是如果您正在使用無伺服器。
設定連線池大小
您可以透過在您的資料庫連線網址中明確設定 connection_limit
參數來指定連線數量。例如,在您的Prisma schema 中使用以下 datasource
配置,連線池將精確地擁有五個連線
datasource db {
provider = "postgresql"
url = "postgresql://johndoe:mypassword@localhost:5432/mydb?connection_limit=5"
}
檢視連線池大小
可以使用日誌記錄和指標來檢視 Prisma Client 使用的連線數量。
使用 info
日誌記錄層級,您可以記錄在實例化 Prisma Client 時開啟的連線池中的連線數量。
例如,考慮以下 Prisma Client 實例和調用
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient({
log: ['info'],
})
async function main() {
await prisma.user.findMany()
}
main()
prisma:info Starting a postgresql pool with 21 connections.
當 PrismaClient
類別被實例化時,日誌記錄通知 stdout
已啟動具有 21 個連線的連線池。
請注意,log: ['info']
產生的輸出可能會在任何版本中變更,恕不另行通知。如果您依賴應用程式或您正在建置的工具中的輸出,請注意這一點。
如果您需要更深入了解您的連線池的大小以及使用中和閒置連線的數量,您可以使用指標功能(目前為預覽版)。
考慮以下範例
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
await Promise.all([prisma.user.findMany(), prisma.post.findMany()])
const metrics = await prisma.$metrics.json()
console.dir(metrics, { depth: Infinity })
}
main()
{
"counters": [
// ...
{
"key": "prisma_pool_connections_open",
"labels": {},
"value": 2,
"description": "Number of currently open Pool Connections"
}
],
"gauges": [
// ...
{
"key": "prisma_pool_connections_busy",
"labels": {},
"value": 0,
"description": "Number of currently busy Pool Connections (executing a datasource query)"
},
{
"key": "prisma_pool_connections_idle",
"labels": {},
"value": 21,
"description": "Number of currently unused Pool Connections (waiting for the next datasource query to run)"
},
{
"key": "prisma_pool_connections_opened_total",
"labels": {},
"value": 2,
"description": "Total number of Pool Connections opened"
}
],
"histograms": [
/** ... **/
]
}
有關指標輸出中可用內容的更多詳細資訊,請參閱關於指標章節。
連線池逾時
預設池逾時
預設連線池逾時為 10 秒。如果查詢引擎在那段時間內沒有從資料庫連線池取得連線,它會拋出例外並繼續處理佇列中的下一個查詢。
設定連線池逾時
您可以透過在您的資料庫連線網址中明確設定 pool_timeout
參數來指定池逾時。在以下範例中,池在 2
秒後逾時
datasource db {
provider = "postgresql"
url = "postgresql://johndoe:mypassword@localhost:5432/mydb?connection_limit=5&pool_timeout=2"
}
停用連線池逾時
您可以將 pool_timeout
參數設定為 0
來停用連線池逾時
datasource db {
provider = "postgresql"
url = "postgresql://johndoe:mypassword@localhost:5432/mydb?connection_limit=5&pool_timeout=0"
}
您可以選擇停用連線池逾時,如果查詢必須保留在佇列中 - 例如,如果您要平行匯入大量記錄,並且確信佇列不會在工作完成之前用完所有可用 RAM。
MongoDB
MongoDB 連接器不使用 Prisma ORM 連線池。連線池由 MongoDB 驅動程式在內部管理,並透過連線字串參數配置。
外部連線池管理工具
您無法將 connection_limit
增加到超出底層資料庫可以支援的範圍。這在無伺服器環境中尤其是一個挑戰,在無伺服器環境中,每個函數管理一個 PrismaClient
實例 - 及其自己的連線池。
考慮引入像 PgBouncer 這樣的外部連線池管理工具,以防止您的應用程式或函數耗盡資料庫連線限制。
手動資料庫連線處理
當使用 Prisma ORM 時,資料庫連線在引擎層級處理。這表示它們不會暴露給開發人員,並且無法手動存取它們。