V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
felixin
V2EX  ›  数据库

在云上开上万个小型独立数据库有什么便宜的方案?

  •  2
     
  •   felixin · 2020-12-30 03:42:04 +08:00 · 5495 次点击
    这是一个创建于 1422 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们的情况是这样子的,我们有一个 sass 平台,用户是面向公众,但是会打算邀请一些外部开发者来我们的平台编写系统的插件,然后插件销售会与作者分成。插件基本上会调用平台提供的一些通用能力,然后会允许插件存储和查询它自己生成的数据。

    现在问题来了,我们假设平台普通用户有 1000 人,每个普通用户购买了 10 个插件,那么我们就需要为每个用户每个插件创建一个单独的数据库来存放数据,因为用户和插件之间的数据是需要隔离的。

    我们不可能真的购买这么多的云数据库,也买不起,目前考虑了这个方案:

    在平台 api 层面把数据存储和读取做成接口,作为平台的能力直接提供给插件调用,这样就避免掉创建新数据库的问题。这个方案唯一的问题就是使得插件放弃了数据库丰富的 sql 语句功能,限制了插件的发挥,所以只能算作次选方案。

    预估每个用户每个插件产生的数据量不会超过 100mb 。最好的方案还是希望云能支持这样一种单实例多租户隔离的数据库服务,但是没有找到这样的服务提供商。

    先谢谢大家了。

    第 1 条附言  ·  2020-12-30 12:30:05 +08:00
    谢谢大家的建议,总结下提出来的方案:

    sqlite:优点单进程最简单,缺点是有并发性能上的问题,一个连接写入数据的时候别的连接无法读取数据。这样可能需要有个 sqlite 管理进程自己实现备份管理,读写分流等。搜索了有个开源的 rqlite 可能能满足需求,需要再研究一下。

    用规范规定开发者必须遵守租户隔离用户数据:优点是把负担转移到开发者上,缺点是还是需要每个插件单独创建数据库(或者每个开发者),如果测试不完备的话可能会出现同一个插件下不同最终用户数据被混淆。然后如果数据库部署在开发者这边,开发者还多了承担数据库维护的责任。

    用 tenant id 单库解析 sql 限定租户:优点是架构简单,缺点是实现复杂,可能无法保证真数据隔离。sql 是图灵完备语言,很难分析全部情况。

    自建数据库实例,用数据库自带的分库(或者 pg 的 schema )管理机制:优点是数据库本身不出 bug 的话,数据是真正隔离开的。目前还没有想到太大的缺点,可能需要自己管理一套数据库工具,不能采用云厂商提供的数据库服务,算是一个缺点。

    控制 docker, k8s 等自动创建数据库容器:优点缺点和上一条应该一样,还有一个可能的缺点就是资源占用有点大。

    修改需求,不要允许开发者使用数据库,用简单存储 kv 等代替:这个方案其实就是只提供有限功能的 Api,我们一开始也是考虑的这个方案,确实值得仔细考虑一下,有提到的 trello 我们得参考下是怎么设计的。优点是完全消解了这个问题,我们推测的缺点可能无法支持聚合等数据库操作,插件比较难给出统计信息等数据,不过这个问题可能可以好好设计一套符合需求的接口来规避。

    再次感谢!
    第 2 条附言  ·  2020-12-30 12:38:52 +08:00
    大家如果知道有类似功能的 sass 平台希望能告知名字,我们可以参考下插件接入设计方式
    56 条回复    2021-02-07 14:24:32 +08:00
    msg7086
        1
    msg7086  
       2020-12-30 04:28:13 +08:00 via Android
    用 docker 跑?
    binux
        2
    binux  
       2020-12-30 04:31:27 +08:00
    sqlite
    webshe11
        3
    webshe11  
       2020-12-30 04:33:13 +08:00 via Android
    sqlite 行吗
    ETiV
        4
    ETiV  
       2020-12-30 04:58:50 +08:00 via iPhone
    一个账号绑定一个 db 不行吗
    账号只能看到自己的 db
    dayeye2006199
        5
    dayeye2006199  
       2020-12-30 06:27:06 +08:00
    gateway + sqlite
    或者一个数据库作为一个容器,跑在 serveless 容器调度平台上(如果不想自己管理 k8s 的话),例如阿里的 ECI
    lihongming
        6
    lihongming  
       2020-12-30 08:29:58 +08:00 via iPhone
    完美解决方案是做个数据服务,让用户间接使用数据库。云数据库很多就是这样的,你用起来没什么区别,但实际上并不是直接操作的数据库。

    不过就你这个情况,可能任何方案都不如租个服务器自己管理数据库便宜,成本只与总存储和总负载有关,开几万个都行
    DivineRapierH
        7
    DivineRapierH  
       2020-12-30 08:47:12 +08:00 via iPhone
    Postgresql 使用 schema 来隔离行不行?
    lichao
        8
    lichao  
       2020-12-30 08:49:40 +08:00
    架构上不合理;考虑修改架构,在一个数据库里完成这些功能。数据隔离并不是必须得单独数据库
    zjsxwc
        9
    zjsxwc  
       2020-12-30 08:52:56 +08:00
    每个用户一个 sqlite 文件
    ffkjjj
        10
    ffkjjj  
       2020-12-30 08:54:44 +08:00 via iPhone
    为什么要为每个用户每个插件单独创建一个数据库?
    mostkia
        11
    mostkia  
       2020-12-30 08:55:21 +08:00
    大量小型数据库,还是用云跑,门槛最低的就是 sqlite 了,挺好的,该有的都有,性能也不差的。各种语言兼容性也挺好
    ghostsf
        12
    ghostsf  
       2020-12-30 09:07:40 +08:00 via iPhone
    多用户多 db 就行了
    whileFalse
        13
    whileFalse  
       2020-12-30 09:07:54 +08:00
    好好重新设计下架构吧。一个插件一个数据库,想什么呢。
    yutian2211
        14
    yutian2211  
       2020-12-30 09:16:41 +08:00
    单实例多租户隔离的数据库服务
    ------------------------------------
    这个不能用数据库权限来实现么?
    用户 db 里面,一个 plugin 库,每个 plugin 有自己的表前缀,比如 plugin_xxx_config 这种

    另外一种:如果可以暴露用户 id 的话,可以做一个单独的 plugin db,与用户 db 隔离。结合上面所说的,就可以完成数据隔离了。
    xuanbg
        15
    xuanbg  
       2020-12-30 09:20:02 +08:00
    楼主你要给每个插件每个用户一个数据库实例???想啥呢,🍑是好吃的吗?

    不过一个插件一个库是可以的,只要每个数据库用户对应一个库就行。然后表里面加一个 tenant_id 字段隔离用户,这个是必须的,插件按平台的规则设计数据结构,差不多就 ok 了。
    zqjnew
        16
    zqjnew  
       2020-12-30 09:20:18 +08:00 via Android
    可以让客户提供数据库服务,
    还可以,解析 sql 语句后,拦截,让用户的表名访问 加上用户插件标识的后缀,即每个用户不同的表,平台拦截对表的访问
    codehz
        17
    codehz  
       2020-12-30 09:28:57 +08:00 via Android
    (全整合在一起岂不是容易一死全死?
    解析用户 sql 语句也很不靠谱,基本上这样搞到最后为了安全都是变成填空模式)
    解决就单独开 SQLite 吧(这样只要提供文件系统隔离就好了
    xuanbg
        18
    xuanbg  
       2020-12-30 09:31:21 +08:00
    就是这个结构:一个插件应用对应一个库
    https://images.i-facture.com/20211230092825.jpg
    reed2020
        19
    reed2020  
       2020-12-30 09:39:40 +08:00
    让我想到用的一个工具软件了,他们的似乎和你的需求很相似。ut ?
    ackoly
        20
    ackoly  
       2020-12-30 09:39:46 +08:00 via iPhone
    我们公司也是做 saas 产品,用的是 mysql,每个实例创建几百个数据库。最多 1 个 8C16G 的实例创建 500 多个库,数据库大概是 1T 空间。
    caola
        21
    caola  
       2020-12-30 09:44:42 +08:00
    sqlite +1
    cccp2020
        22
    cccp2020  
       2020-12-30 10:07:53 +08:00
    买两台按量付费的服务器,然后对比一下两种方案产生的费用呢
    doublleft
        23
    doublleft  
       2020-12-30 10:15:35 +08:00
    是啊 改造成租户模式,共享一个大池子
    star7th
        24
    star7th  
       2020-12-30 10:22:48 +08:00
    自己买服务器,自建数据库。起一个实例即可,然后一个用户一个数据库给他们用。
    yzbythesea
        25
    yzbythesea  
       2020-12-30 10:25:10 +08:00
    插件开发者自己用 data account 存数据啊,不需要你们维护。你们给权限,让他们插件运行的时候,可以从你们的 compute account 查询 他们自己的 data account 数据就可以了。
    GM
        26
    GM  
       2020-12-30 11:34:07 +08:00
    自己装 mysql 或者 pgsql,然后每个用户一个独立 db,非常简单。
    no1xsyzy
        27
    no1xsyzy  
       2020-12-30 12:04:22 +08:00
    sqlite 最明显的弊端是并发低(文件加锁多进程操作必须串行),但你这个场景看上去确实不存在并发
    不过,为什么要 SQL ?大部分插件基本上一个 kv 最多一个 json 就能解决了。
    实在需要真的数据库的,你可以允许插件编写者使用自己的数据库,开 OAuth2 之类的进行用户鉴权。
    (以上均参考 Trello,可以看下 dump 整个看板的 API,就一个 json 包含所有插件信息)
    lekai63
        28
    lekai63  
       2020-12-30 12:14:00 +08:00
    Postgresql 使用 schema
    如果要 NoSQL 的话,试试 Postgres 的插件咯
    felixin
        29
    felixin  
    OP
       2020-12-30 12:29:56 +08:00 via Android
    谢谢大家的建议,总结下提出来的方案:

    sqlite:优点单进程最简单,缺点是有并发性能上的问题,一个连接写入数据的时候别的连接无法读取数据。这样可能需要有个 sqlite 管理进程自己实现备份管理,读写分流等。搜索了有个开源的 rqlite 可能能满足需求,需要再研究一下。

    用规范规定开发者必须遵守租户隔离用户数据:优点是把负担转移到开发者上,缺点是还是需要每个插件单独创建数据库(或者每个开发者),如果测试不完备的话可能会出现同一个插件下不同最终用户数据被混淆。然后如果数据库部署在开发者这边,开发者还多了承担数据库维护的责任。

    用 tenant id 单库解析 sql 限定租户:优点是架构简单,缺点是实现复杂,可能无法保证真数据隔离。sql 是图灵完备语言,很难分析全部情况。

    自建数据库实例,用数据库自带的分库(或者 pg 的 schema )管理机制:优点是数据库本身不出 bug 的话,数据是真正隔离开的。目前还没有想到太大的缺点,可能需要自己管理一套数据库工具,不能采用云厂商提供的数据库服务,算是一个缺点。

    控制 docker, k8s 等自动创建数据库容器:优点缺点和上一条应该一样,还有一个可能的缺点就是资源占用有点大。

    修改需求,不要允许开发者使用数据库,用简单存储 kv 等代替:这个方案其实就是只提供有限功能的 Api,我们一开始也是考虑的这个方案,确实值得仔细考虑一下,有提到的 trello 我们得参考下是怎么设计的。优点是完全消解了这个问题,我们推测的缺点可能无法支持聚合等数据库操作,插件比较难给出统计信息等数据,不过这个问题可能可以好好设计一套符合需求的接口来规避。

    再次感谢!
    opengps
        30
    opengps  
       2020-12-30 12:30:47 +08:00 via Android
    既然你是云端服务,每个用户一个独立库的意义在哪?同一个库的权限隔离也能满足功能,是有什么硬指标要求的吗?
    felixin
        31
    felixin  
    OP
       2020-12-30 12:39:07 +08:00 via Android
    大家如果知道有类似功能的 sass 平台希望能告知名字,我们可以参考下插件接入设计方式
    CODEWEA
        32
    CODEWEA  
       2020-12-30 12:46:28 +08:00
    一个用户根据唯一 id 分配数据库就行了,做好权限分配就行了
    musi
        33
    musi  
       2020-12-30 12:52:40 +08:00 via iPhone
    要不参考下微信小程序的云开发?不过他们的是 mongoDB
    felixin
        34
    felixin  
    OP
       2020-12-30 13:30:44 +08:00 via Android
    @musi mongodb 确实不错,就是不知道微信是怎么做权限隔离的


    @opengps 主要是为了隔离不同用户的数据,插件之间由于是不同的开发者,也希望互相不要有影响,同一个库的权限隔离必须要开发者遵守一定规范才能做到,如果我们允许任意开发者来上传插件,这样就不太安全了
    littlewing
        35
    littlewing  
       2020-12-30 13:34:26 +08:00 via iPhone
    mysql 可以给用户授权
    jinsongzhao
        36
    jinsongzhao  
       2020-12-30 13:38:48 +08:00
    数据库都支持隔离, 开不同账号, 如果客户一定要用超级管理员才放心, 那应该是专业用户了, 那真没招, 只能 sqlite 了. 总之开多个数据库服务肯定不行.
    kwklover
        37
    kwklover  
       2020-12-30 14:20:01 +08:00
    sqlite 或单机版的 NOSQL 都可以的,当然这些数据库的并发与事务性肯定不如关系型数据库。但是小的用户其实对并发和故障率要求并不高。
    可以这样设计:
    每个插件用一个单机版 NOSQL 做数据存储,使用的时候全部 LOAD 入内存,完全没有并发问题了,不过可能存在稳定性问题,所以需要把插件的数据设计成一个可序列化的对象存储到 mysql 中某个表当做备份,一个插件,一条记录即可。
    liuxu
        38
    liuxu  
       2020-12-30 14:22:09 +08:00
    多 DB 多用户隔离
    40EaE5uJO3Xt1VVa
        39
    40EaE5uJO3Xt1VVa  
       2020-12-30 16:01:56 +08:00   ❤️ 1
    一定要在云上嘛,我现在都用 frp 把部分吃 CPU 的部分业务放到办公室租的三个刀片机上,用 frp 做内网穿透出去,延迟也就是多个二三十 ms
    DoctorCat
        40
    DoctorCat  
       2020-12-30 16:20:47 +08:00
    @yanzhiling2001 这种属于自建机房的方案,如果保障 SLA 和响应速度,那成本其实也不低的。
    DoctorCat
        41
    DoctorCat  
       2020-12-30 16:22:42 +08:00
    lz 还要考虑运维成本
    40EaE5uJO3Xt1VVa
        42
    40EaE5uJO3Xt1VVa  
       2020-12-30 17:48:29 +08:00
    @DoctorCat 组了三个刀片机装 PVE,成本在 5w 左右,然后拉了一根企业宽带,3w+ ,还给了几个固定的公网 IP,企业宽带用 frp 连接到云上延迟非常稳定。成本就这些,比起业务全上云还更划算。
    namelosw
        43
    namelosw  
       2020-12-30 18:10:09 +08:00
    你去 Heroku 搞一个免费的 Postgres, 用 Datagrip 连上之后会发现有几千个“邻居”库, 虽然你打不开, 但是能看到名字. 所以感觉分库是个思路.

    Docker 之类的可能太浪费资源了.

    ---

    > 我们假设平台普通用户有 1000 人,每个普通用户购买了 10 个插件,那么我们就需要为每个用户每个插件创建一个单独的数据库来存放数据,因为用户和插件之间的数据是需要隔离的。

    感觉你可以再想想, 好像这个情况不需要很多数据库, 只要控制好数据隔离就行了, 除非有啥法律和合同限制. 插件的话看语言, 比如 JS 有 realms, 就可以很容易的 sandbox 用户可以干啥.
    DoctorCat
        44
    DoctorCat  
       2020-12-30 18:35:11 +08:00
    DoctorCat
        45
    DoctorCat  
       2020-12-30 18:35:44 +08:00
    电力冗余、空调系统呢?
    crclz
        46
    crclz  
       2020-12-30 18:51:39 +08:00
    为啥不给每一个开发者开一个 database ?( Postgres 的"Schema",mongodb 的"database"),在分配给每个开发者一个账户
    musi
        47
    musi  
       2020-12-30 19:08:35 +08:00
    @felixin 我们也做了一套,是基于 db 来做数据隔离的,阿里云还有个 serverless 版本,就是多租户的,就是一个月七八十,这个我们拿来做用户付费方案了
    40EaE5uJO3Xt1VVa
        48
    40EaE5uJO3Xt1VVa  
       2020-12-30 21:25:52 +08:00
    @DoctorCat

    身处工业区,确认过了,和旁边玻璃厂 陶瓷厂 易拉罐厂共用一个办公楼和电力系统,完全不用考虑电力冗余,他们停电的损失几十万起步。

    机柜放在一个单独屋子里,有空调和风扇。现在秋冬天还好,之前夏天时候,委托同事上班路过到附近干冰厂提两箱干冰辅助降温
    viakiba
        49
    viakiba  
       2020-12-31 09:01:48 +08:00 via iPhone
    serverlessdb
    abersheeran
        50
    abersheeran  
       2020-12-31 09:42:34 +08:00
    @crclz mongodb 的 database 可以允许单实例开启数万乃至数十万个吗?
    crclz
        51
    crclz  
       2020-12-31 10:33:28 +08:00
    @abersheeran 你可以多机啊
    abersheeran
        52
    abersheeran  
       2020-12-31 11:12:38 +08:00
    @crclz 嗯,我知道集群。不过我的意思是,几万几十万的 database 会不会带来太多不必要的压力?
    crclz
        53
    crclz  
       2020-12-31 13:04:02 +08:00
    @abersheeran 不是集群,不是集群。如果你要开 50000 个 database,那么就拿 10 台机器出来,一台开 5000 个。再说账号也是存放在数据库里面的(由系统自己管理),50000 账号也只是 50000 条记录而已,实际的压力还是要看执行的 SQL 的量。
    DoctorCat
        54
    DoctorCat  
       2020-12-31 13:52:05 +08:00
    @yanzhiling2001 你们老板太省了 🤦‍♂️
    abersheeran
        55
    abersheeran  
       2020-12-31 17:12:16 +08:00
    @crclz 这样的啊。那看起来 mongodb 的 database 很轻量?我看其他数据库都不推荐开这么多 database 。
    SilenceLL
        56
    SilenceLL  
       2021-02-07 14:24:32 +08:00
    跟我们有点类似,我们之前好像是几百台数据库主机,每台数据库主机放 5000 个用户。每个用户的请求通过配置表路由转发到实际的数据库实例
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1116 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 18:41 · PVG 02:41 · LAX 10:41 · JFK 13:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.