找回密码
 立即注册
首页 业界区 业界 VonaJS提供的读写分离,直观,优雅

VonaJS提供的读写分离,直观,优雅

锟及 2025-9-29 08:29:40
在VonaJS中实现读写分离,只需提供一组写数据源和一组读数据源。当用户访问后端 API 时,系统会按照规则自动选择写数据源或读数据源,访问相应的数据库,从而分摊压力,提升系统性能
安装模块

读写分离作为独立的模块提供,因此需要在VonaJS项目中安装此模块:
  1. $ pnpm add vona-module-a-datasharding -w
复制代码
添加数据源

首先,需要添加一组数据源
1. 添加类型定义

为新数据源添加类型定义
src/backend/config/config/config.ts
  1. declare module 'vona-module-a-orm' {
  2.   export interface IDatabaseClientRecord {
  3.     read1: never;
  4.     read2: never;
  5.     write1: never;
  6.     write2: never;
  7.   }
  8. }
复制代码
2. 增加数据源配置

src/backend/config/config/config.ts
  1. // database
  2. config.database = {
  3.   clients: {
  4.     read1: {
  5.       client: 'pg',
  6.       connection: {
  7.         host: '127.0.0.1',
  8.         port: 5432,
  9.         user: 'postgres',
  10.         password: '',
  11.         database: 'xxxx-read1',
  12.       },
  13.     },
  14.     read2: {...},
  15.     write1: {...},
  16.     write2: {...},
  17.   },
  18. };
复制代码
配置读写数据源

然后配置模块的读写数据源
src/backend/config/config/config.ts
  1. // modules
  2. config.modules = {
  3.   'a-datasharding': {
  4.     client: {
  5.       reads: ['read1', 'read2'],
  6.       writes: ['write1', 'write2'],
  7.       randomRead: undefined,
  8.       randomWrite: undefined,
  9.     },
  10.   },
  11. };   
复制代码
名称说明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
  1. // onions
  2. config.onions = {
  3.   summerCache: {
  4.     'a-datasharding:datasourceWrite': {
  5.       mem: {
  6.         ttl: 5 * 1000, // 5s
  7.       },
  8.       redis: {
  9.         ttl: 5 * 1000, // 5s
  10.       },
  11.     },
  12.   },
  13. };
复制代码
名称说明mem.ttlMem缓存的过期时间,默认为3秒redis.ttlRedis缓存的过期时间,默认为3秒数据一致性: 缓存双删

场景分析:不同用户

Vona ORM 提供了开箱即用的缓存机制,参见:缓存
由于数据库同步有延时,会出现缓存不一致性的情况。比如,用户 A 访问Write-API,将数据写入写数据库,并自动删除缓存。接下来,用户 B 访问Read-API,此时读数据库还没有同步,那么就会读到旧数据,并存入缓存
为了解决以上问题,模块a-orm提供了缓存双删机制:当用户 A 访问Write-API时,将数据写入写数据库,并自动删除缓存。然后在指定时间之后再次删除缓存,从而确保缓存总是最新数据
启用缓存双删

src/backend/config/config/config.ts
  1. // modules
  2. config.modules = {
  3.   'a-orm': {
  4.     sharding: {
  5.       cache: {
  6.         doubleDelete: true,
  7.       },
  8.     },
  9.   },
  10. };
复制代码
修改缓存双删延迟时间

系统采用队列任务执行缓存双删,队列名称是a-orm:doubleDelete,可以在 App config 中修改缓存双删延迟时间:
src/backend/config/config/config.ts
  1. // onions
  2. config.onions = {
  3.   queue: {
  4.     'a-orm:doubleDelete': {
  5.       options: {
  6.         job: {
  7.           delay: 5 * 1000, // 5s
  8.         },
  9.       },
  10.     },
  11.   },
  12. };
复制代码
名称说明job.delay指定延迟多长时间执行缓存双删任务,默认为3秒Vona ORM已开源:https://github.com/vonajs/vona

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册