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提供的读写分离,直观,优雅🌼的更多相关文章
- DBPack 读写分离功能发布公告
在 v0.1.0 版本我们发布了分布式事务功能,并提供了读写分离功能预览.在 v0.2.0 这个版本,我们加入了通过 UseDB hint 自定义查询请求路由的功能,并修复了一些 bug.另外,在这个 ...
- 探讨EFCore如何优雅的实现读写分离
前言 我们都知道当单库系统遇到性能瓶颈时,读写分离是首要优化手段之一.因为绝大多数系统读的比例远高于写的比例,并且大量耗时的读操作容易引起锁表导致无发写入数据,这时读写分离就更加重要了. ...
- Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解
转载:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...
- MyCAT实现MySQL的读写分离
在MySQL中间件出现之前,对于MySQL主从集群,如果要实现其读写分离,一般是在程序端实现,这样就带来一个问题,即数据库和程序的耦合度太高,如果我数据库的地址发生改变了,那么我程序端也要进行相应的修 ...
- Nginx反向代理、负载均衡、页面缓存、URL重写及读写分离详解
大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统 ...
- Nginx 反向代理、负载均衡、页面缓存、URL重写、读写分离及简单双机热备详解
大纲 一.前言 二.环境准备 三.安装与配置Nginx (windows下nginx安装.配置与使用) 四.Nginx之反向代理 五.Nginx之负载均衡 (负载均衡算法:nginx负载算法 up ...
- Nginx反向代理 负载均衡 页面缓存 URL重写及读写分离
大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统 ...
- MyCAT部署及实现读写分离(转)
MyCAT是mysql中间件,前身是阿里大名鼎鼎的Cobar,Cobar在开源了一段时间后,不了了之.于是MyCAT扛起了这面大旗,在大数据时代,其重要性愈发彰显.这篇文章主要是MyCAT的入门部署. ...
- [转载]Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解
大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统 ...
- MySQL ProxySQL读写分离使用初探
目的 在美团点评DBProxy读写分离使用说明文章中已经说明了使用目的,本文介绍ProxySQL的使用方法以及和DBProxy的性能差异.具体的介绍可以看官网的相关说明,并且这个中间件也是percon ...
随机推荐
- java 两个线程
简介 使用synchronized, 来实现两个线程的同步操作. 参考链接 https://www.cnblogs.com/leihuazhe/p/7898563.html TIPS 唤醒一个在等待资 ...
- raspberry 用户管理
sudo adduser bob增加用户 sudo passwd bob修改用户的密码 sudo visudo 修改用户sudo的权限 bob ALL = NOPASSWD: ALL bob使用sud ...
- java PriorityQueueTest.java
简介 优先级队列内部采用大顶堆或者小顶堆实现 code import java.util.*; import java.time.*; public class PriorityQueueTest { ...
- 底层架构剖析:国内 iPaaS 开发效率与稳定性双优,国外 ESB 为何落后?
一.引言 现在很多企业都在讲数字化.智能化型,而这几年iPaaS集成平台已经从"可选"走向"必选".企业想要快速实现数据共享.业务联动.流程协同,最基础的一步就 ...
- OpenList挂载「百度网盘」
01 基础挂载设置 存储->添加 选择百度网盘 填写挂载路径 策略可选用302代理,也可选用本地代理 下载接口使用官方.online api 关掉 获取客户端ID.密钥以及刷新令牌(在下面几步中 ...
- 洛谷题解 | P3383 【模板】线性筛素数
题目思路 先思考最朴素的素数筛法.即对于每个数 \(n\),检查它是否能被任意小于 \(\sqrt{n}\) 的整数整除.如果不能,则 \(n\) 是素数.这种筛法显然是低效的. 逆向思考,上述素数筛 ...
- 标准结构篇:9.1)JB5054-2000流程
本章目的:了解这个最基础的产品设计研发流程标准 1.前言 JB5054-2000流程是2000年的研发流程,如果你自家公司的研发流程环节或提交资料比这个还少,就真的要考虑一下,到底是什么地方漏了. 2 ...
- Go 原理之 gc 垃圾回收机制:三色标记 + 混合写屏障(需要 STW)
Go 原理之 gc 垃圾回收机制 一.常见垃圾回收算法 垃圾回收算法 描述 代表语言 优缺点 引用计数 为每个对象维护一个引用计数,记录对象被引用的次数每当一个对象被引用时,引用计数就会增加.当对象不 ...
- Unity3D 中的简单 Steam 创意工坊实现
添加 Steamworks 软件包 转到 https://github.com/rlabrecque/Steamworks.NET/releases 并下载最新版本,确保下载 .unitypackag ...
- windows 安装Zookeeper 配置集群
Windows安装Zookeeper 并配置集群 1.安装java环境 ZooKeeper 在 Java 中运行,版本 1.8 或更高(JDK 8 LTS.JDK 11 LTS.JDK 12 - Ja ...