Skip to content
This repository has been archived by the owner on Aug 15, 2023. It is now read-only.

数据库添加新后端 #405

Closed
3 tasks
Arondight opened this issue Nov 18, 2021 · 7 comments
Closed
3 tasks

数据库添加新后端 #405

Arondight opened this issue Nov 18, 2021 · 7 comments
Assignees
Labels
enhancement New feature or request wontfix This will not be worked on

Comments

@Arondight
Copy link
Owner

Arondight commented Nov 18, 2021

问题描述

目前 lowdb 的性能问题实在是太严重了,在我实现了数据库定时清理后,因为数据库不会再无限制增长了而稍微掩盖了一下这个问题,但是在一个极大量用户的 bot 中,lowdb 根本无法胜任。我的想法是增加一个新的、非关系型的后端,然后两个后端可以使用 setting.yml 中的配置选项进行切换(暂时不考虑数据同步,或者使用在 tools 下的脚本进行同步),默认使用 lowdb 。我无法割舍 lowdb 能够极大简化 bot 部署步骤的优点,但是也无法忍受 lowdb 在并发场景中的低效。

对于新后端的要求,我的想法是编程上尽可能的易于实现,能够用最小的代码量把当前的 database.js 迁移过去,最终能够让调用者无感。目前我只是有一个想法,还没有去仔细想怎么做这件事。当前我比较倾向于 MongoDB 。

Q:为什么首先想到的不是 Redis 或者 sqlite ?
A:因为 MongoDB 的文档存储更加像 lowdb ,我可以更容易的把当前的逻辑都迁移到新后端上,而 Redis 的键值对存储需要更改数据库实现逻辑和使用场景。对我来说 MongoDB 只是一个 lowdb 的威力加强版 Plus Pro Max ;至于 sqlite ,它的确很适合 bot 使用的场景,也不会带来繁琐的部署流程,但是对于我来说编码工作太多了,把当前的数据库 API 迁移到一个关系型数据库的后端上需要更多的工作量。再者 sqlite 的锁级只能到文件,读写时会整个把数据库锁住,我并不觉得 sqlite 相对于 lowdb 有什么质变。

Q:关于数据库可选后端的部署想法?
A:Docker 部署,文档中提供命令,仓库中提供配置文件。但是项目本身不会提供(本项目的) docker 镜像,我更倾向于使用 Git 定时更新并使用 pm2 管理 bot 。

  • 实现 MongoDB 的数据库后端
  • 实现数据库后端的切换
  • 实现后端之间的数据迁移

这可能是一个长期的工作,或许要花费数周甚至更长的时间。

代码状态:当前提交

f27b71b

@Arondight Arondight added enhancement New feature or request question Further information is requested todo The to do list labels Nov 18, 2021
@Arondight Arondight self-assigned this Nov 18, 2021
@Arondight
Copy link
Owner Author

MongoDB docker image

MongoDB Node.js module

#dbEngine: lowdb
dbEngine: mongo
mongoHost: localhost
mongoPort: 9944
mongoUser: adachi
mongoPass: adachi
npm run datasync -- --low-to-mongo
npm run datasync -- --mongo-to-low

@Arondight
Copy link
Owner Author

因为 docker 和 bot 开机启动有一个依赖关系,所以当使用 mongo 时, bot 连接数据库失败后不应该放弃,而是不断轮询直到成功。

@Arondight Arondight removed the question Further information is requested label Nov 21, 2021
@490720818
Copy link
Contributor

只是为了性能的话mongodb应该还不如sqlite

@Arondight
Copy link
Owner Author

只是为了性能的话mongodb应该还不如sqlite

为啥呢

@Arondight
Copy link
Owner Author

Arondight commented Nov 29, 2021

// const { MongoClient } = require('mongodb');
// or as an es module:
import { MongoClient } from "mongodb";

// Connection URL
const url = "mongodb://adachi:adachi@127.0.0.1:9933";
const client = new MongoClient(url);

// Database Name
const dbName = "adachi";

async function main() {
  // Use connect method to connect to the server
  await client.connect();
  console.log("Connected successfully to server");
  const db = client.db(dbName);
  const collection = db.collection("documents");

  // the following code examples can be pasted here...
  const insertResult = await collection.insertMany([{ a: 1 }, { a: 2 }, { a: 3 }]);
  console.log("Inserted documents =>", insertResult);
  const findResult = await collection.find({}).toArray();
  console.log("Found documents =>", findResult);
  const filteredDocs = await collection.find({ a: 3 }).toArray();
  console.log("Found documents filtered by { a: 3 } =>", filteredDocs);
  const updateResult = await collection.updateOne({ a: 3 }, { $set: { b: 1 } });
  console.log("Updated documents =>", updateResult);
  const deleteResult = await collection.deleteMany({ a: 3 });
  console.log("Deleted documents =>", deleteResult);
  const indexName = await collection.createIndex({ a: 1 });
  console.log("index name =", indexName);

  return "done.";
}

main()
  .then(console.log)
  .catch(console.error)
  .finally(() => client.close());
Connected successfully to server
Inserted documents => {
  acknowledged: true,
  insertedCount: 3,
  insertedIds: {
    '0': new ObjectId("61a4a032105744d7d68a027d"),
    '1': new ObjectId("61a4a032105744d7d68a027e"),
    '2': new ObjectId("61a4a032105744d7d68a027f")
  }
}
Found documents => [
  { _id: new ObjectId("61a4a032105744d7d68a027d"), a: 1 },
  { _id: new ObjectId("61a4a032105744d7d68a027e"), a: 2 },
  { _id: new ObjectId("61a4a032105744d7d68a027f"), a: 3 }
]
Found documents filtered by { a: 3 } => [ { _id: new ObjectId("61a4a032105744d7d68a027f"), a: 3 } ]
Updated documents => {
  acknowledged: true,
  modifiedCount: 1,
  upsertedId: null,
  upsertedCount: 0,
  matchedCount: 1
}
Deleted documents => { acknowledged: true, deletedCount: 1 }
index name = a_1
done.

@Arondight
Copy link
Owner Author

实际上 mongo 部署起来仍然很方便,我有点犹豫要不要留着 lowdb 了, lowdb 唯一的意义就在于 windows 上部署方便了

@Arondight
Copy link
Owner Author

MongoDB 大致调了一下,测试数据已经调通,不过两个数据库同步数据没有调通,但是我意识到 MongoDB NodeJS Driver 不支持同步方法后,觉得使用 MongoDB 带来的好处无法平衡代码改动带来的影响。我尝试使用 DeAsync.js,但是马上意识到这不是一个好主意。这个功能将停止开发, #485 将替代此功能。

@Arondight Arondight added wontfix This will not be worked on and removed todo The to do list labels Dec 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants