绩效比较:还原车站与Minio
#教程 #database #s3 #reductstore

如果我们需要在云或
中的某个地方存储不同格式和尺寸的数据,我们通常会使用blob存储 我们的内部存储。 Minio是S3兼容存储,您可以在私有云,裸机服务器
上运行它 甚至在边缘设备上。您也可以将其调整为将历史数据作为斑点的时间序列。最多的
直接解决方案是为每个数据源创建一个文件夹,并在其
中使用时间戳保存对象 名称:

bucket
 |
 |---cv_camera
        |---1666225094312397.bin
        |---1666225094412397.bin
        |---1666225094512397.bin

如果您需要查询数据,则应请求cv_camera文件夹中的对象列表,然后按名称过滤
根据给定的时间间隔。
这种方法易于实施,但有一些缺点:

  • 文件夹的对象越多,查询的时间越长。
  • 小对象的大开销:由于字符串和最小文件大小为1KB或512 文件系统。
  • FIFO配额,要在我们达到一定限制时删除旧数据,可能对密集的写作操作不起作用。

ReductStore旨在解决这些问题。它具有强大的FIFO配额,用于通过时间查询数据的HTTP API
间隔,并将对象(或记录)组合到块中,以进行有效的磁盘使用和搜索。

MinioReductStore具有Python SDK,因此我们可以使用它们来实施读写操作并比较

性能。

用Minio读/写数据

对于基准测试,我们创建了两个函数来编写和读取CHUNK_COUNT块:

from minio import Minio
import time

minio_client = Minio("127.0.0.1:9000", access_key="minioadmin", secret_key="minioadmin", secure=False)


def write_to_minio():
    count = 0
    for i in range(CHUNK_COUNT):
        count += CHUNK_SIZE
        object_name = f"data/{str(int(time.time_ns() / 1000))}.bin"
        minio_client.put_object(BUCKET_NAME, object_name, io.BytesIO(CHUNK),
                                CHUNK_SIZE)
    return count  # count data to print it in main function


def read_from_minio(t1, t2):
    count = 0

    t1 = str(int(t1 * 1000_000))
    t2 = str(int(t2 * 1000_000))

    for obj in minio_client.list_objects("test", prefix="data/"):
        if t1 <= obj.object_name[5:-4] <= t2:
            resp = minio_client.get_object("test", obj.object_name)
            count += len(resp.read())

    return count

您可以看到minio_client不提供任何带有模式的API查询数据,因此我们必须浏览整个文件夹
在客户端找到所需的对象。如果您有数十亿个对象,则停止工作。您必须存储
某些时间序列数据库中的对象路径或创建文件夹的层次结构,例如每天创建一个新文件夹。

使用还原店读取/编写数据

使用ReductStore这要容易得多:

from reduct import Client as ReductClient

reduct_client = ReductClient("http://127.0.0.1:8383")


async def write_to_reduct():
    count = 0
    bucket = await reduct_client.create_bucket("test", exist_ok=True)
    for i in range(CHUNK_COUNT):
        await bucket.write("data", CHUNK)
        count += CHUNK_SIZE
    return count


async def read_from_reduct(t1, t2):
    count = 0
    bucket = await reduct_client.get_bucket("test")
    async for rec in bucket.query("data", int(t1 * 1000000), int(t2 * 1000000)):
        count += len(await rec.read_all())
    return count

基准

当我们具有写入/读取功能时,我们最终可以写下我们的基准:

import io
import random
import time
import asyncio

from minio import Minio
from reduct import Client as ReductClient

CHUNK_SIZE = 100000
CHUNK_COUNT = 10000
BUCKET_NAME = "test"

CHUNK = random.randbytes(CHUNK_SIZE)

minio_client = Minio("127.0.0.1:9000", access_key="minioadmin", secret_key="minioadmin", secure=False)
reduct_client = ReductClient("http://127.0.0.1:8383")

# Our function were here..

if __name__ == "__main__":
    print(f"Chunk size={CHUNK_SIZE / 1000_000} Mb, count={CHUNK_COUNT}")
    ts = time.time()
    size = write_to_minio()
    print(f"Write {size / 1000_000} Mb to Minio: {time.time() - ts} s")

    ts_read = time.time()
    size = read_from_minio(ts, time.time())
    print(f"Read {size / 1000_000} Mb from Minio: {time.time() - ts_read} s")

    loop = asyncio.new_event_loop();
    ts = time.time()
    size = loop.run_until_complete(write_to_reduct())
    print(f"Write {size / 1000_000} Mb to ReductStore: {time.time() - ts} s")

    ts_read = time.time()
    size = loop.run_until_complete(read_from_reduct(ts, time.time()))
    print(f"Read {size / 1000_000} Mb from ReductStore: {time.time() - ts_read} s")

用于测试,我们需要运行数据库。 docker-compose很容易:

services:
  reduct-storage:
    image: reductstorage/engine:v1.0.1
    volumes:
      - ./reduct-data:/data
    ports:
      - 8383:8383

  minio:
    image: minio/minio
    volumes:
      - ./minio-data:/data
    command: minio server /data --console-address :9002
    ports:
      - 9000:9000
      - 9002:9002

运行Docker组成配置和基准:

docker-compose up -d
python3 main.py

结果

脚本打印给定的chunk_size和CHUNK_COUNT的结果。在我的设备上,我得到以下数字:

操作 minio 还原店
10.0 MB(100个请求) 8.69 S 0.53 S
阅读 1.19 S 0.57 S
1.0 MB(1000请求) 12.66 S 1.30 S
阅读 2.04 S 1.38 S
.1 MB(10000请求) 61.86 S 13.73 S
阅读 9.39 S 15.02 S

如您所见,ReductStore的写作操作总是更快(10 MB斑点的16倍!!!),有点
当我们有许多小物体时,阅读速度较慢。您可能会注意到,当我们
时,两个数据库的速度都会降低 减少块的大小。这可以用HTTP开销来解释,因为我们花费了专用的HTTP请求
每个写或读取操作。

结论

ReductStore可能是您需要使用时间戳和
存储斑点的应用程序的一个不错的选择 连续写数据。它具有强大的FIFO配额来避免磁盘空间问题,并且对于密集的
来说非常快 写操作。

参考: