VonaJS提供的讀寫分離,直觀,優雅🌼
在VonaJS中實現讀寫分離,只需提供一組寫數據源和一組讀數據源。當用戶訪問后端 API 時,系統會按照規則自動選擇寫數據源或讀數據源,訪問相應的數據庫,從而分攤壓力,提升系統性能
安裝模塊
讀寫分離作為獨立的模塊提供,因此需要在VonaJS項目中安裝此模塊:
$ pnpm add vona-module-a-datasharding -w
添加數據源
首先,需要添加一組數據源
1. 添加類型定義
為新數據源添加類型定義
src/backend/config/config/config.ts
declare module 'vona-module-a-orm' {
export interface IDatabaseClientRecord {
read1: never;
read2: never;
write1: never;
write2: never;
}
}
2. 增加數據源配置
src/backend/config/config/config.ts
// database
config.database = {
clients: {
read1: {
client: 'pg',
connection: {
host: '127.0.0.1',
port: 5432,
user: 'postgres',
password: '',
database: 'xxxx-read1',
},
},
read2: {...},
write1: {...},
write2: {...},
},
};
配置讀寫數據源
然后配置模塊的讀寫數據源
src/backend/config/config/config.ts
// modules
config.modules = {
'a-datasharding': {
client: {
reads: ['read1', 'read2'],
writes: ['write1', 'write2'],
randomRead: undefined,
randomWrite: undefined,
},
},
};
| 名稱 | 說明 |
|---|---|
| reads | 指定一組讀數據源 |
| writes | 指定一組寫數據源 |
| randomRead | 可指定自定義函數,從reads中提取一個讀數據源。默認為undefined,由系統隨機提取 |
| randomWrite | 可指定自定義函數,從writes中提取一個寫數據源。默認為undefined,由系統隨機提取 |
讀寫分離的運行機制
當配置好讀寫數據源之后,讀寫分離機制就自動生效了
現在,解釋一下讀寫分離的運行機制:
模塊提供了一個全局攔截器
a-datasharding:datasharding。該攔截器判斷當前 API Method,如果是POST/PATCH/DELETE/PUT,那么就使用寫數據源,否則使用讀數據源
數據一致性: 緩存寫數據源
場景分析:同一個用戶
由于數據庫同步有延時,會出現數據不一致性的情況。比如,用戶訪問Write-API,將數據寫入寫數據庫。接下來,用戶訪問Read-API,此時讀數據庫還沒有同步,那么就會讀到舊數據
為了解決以上問題,模塊自動提供了一個機制:當用戶訪問Write-API時,會自動將寫數據源存入二級緩存,并設置過期時間。在這個時間之內,用戶訪問Read-API時,也會繼續使用同一個寫數據源,從而確保在寫入數據后總是可以讀取到最新的數據
修改過期時間
二級緩存的名稱是a-datasharding:datasourceWrite,可以在 App config 中修改過期時間:
src/backend/config/config/config.ts
// onions
config.onions = {
summerCache: {
'a-datasharding:datasourceWrite': {
mem: {
ttl: 5 * 1000, // 5s
},
redis: {
ttl: 5 * 1000, // 5s
},
},
},
};
| 名稱 | 說明 |
|---|---|
| mem.ttl | Mem緩存的過期時間,默認為3秒 |
| redis.ttl | Redis緩存的過期時間,默認為3秒 |
數據一致性: 緩存雙刪
場景分析:不同用戶
Vona ORM 提供了開箱即用的緩存機制,參見:緩存
由于數據庫同步有延時,會出現緩存不一致性的情況。比如,用戶 A 訪問Write-API,將數據寫入寫數據庫,并自動刪除緩存。接下來,用戶 B 訪問Read-API,此時讀數據庫還沒有同步,那么就會讀到舊數據,并存入緩存
為了解決以上問題,模塊a-orm提供了緩存雙刪機制:當用戶 A 訪問Write-API時,將數據寫入寫數據庫,并自動刪除緩存。然后在指定時間之后再次刪除緩存,從而確保緩存總是最新數據
啟用緩存雙刪
src/backend/config/config/config.ts
// modules
config.modules = {
'a-orm': {
sharding: {
cache: {
doubleDelete: true,
},
},
},
};
修改緩存雙刪延遲時間
系統采用隊列任務執行緩存雙刪,隊列名稱是a-orm:doubleDelete,可以在 App config 中修改緩存雙刪延遲時間:
src/backend/config/config/config.ts
// onions
config.onions = {
queue: {
'a-orm:doubleDelete': {
options: {
job: {
delay: 5 * 1000, // 5s
},
},
},
},
};
| 名稱 | 說明 |
|---|---|
| job.delay | 指定延遲多長時間執行緩存雙刪任務,默認為3秒 |
Vona ORM已開源:https://github.com/vonajs/vona

在VonaJS中實現讀寫分離,只需提供一組寫數據源和一組讀數據源。當用戶訪問后端 API 時,系統會按照規則自動選擇寫數據源或讀數據源,訪問相應的數據庫,從而分攤壓力,提升系統性能
浙公網安備 33010602011771號