缓存数据:Numpy、Pandas与MySQL对比——MySQL缓存额外优势探讨
我目前正在处理存储于H5文件中的时序数据,每个文件包含一小时的数据。为向实时处理转型,计划按秒处理时序数据:聚合一秒的数据、处理数据、清空缓存并重复该流程。
最初打算用NumPy Array或Pandas DataFrame实现此方案,但同事建议改用MySQL数据库缓存数据。为基准测试三种方案的性能,我开展了简单的计时实验,测试访问1000条样本的耗时,结果如下:
| Method | Execution time |
|---|---|
| Pandas | 1.36 µs |
| NumPy | 790 ns |
| MySQL | 552 ns |
测试所用代码如下:
Benchmark 代码
import pandas as pd import numpy as np import mysql.connector from timeit import timeit
Pandas DataFrame 测试
df = pd.DataFrame() df['test'] = np.arange(1,1000) %timeit df['test']
测试结果:1.36 µs ± 26.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
NumPy Array 测试
%timeit np.arange(1,1000)
测试结果:790 ns ± 21.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
MySQL 数据库测试
cnx = mysql.connector.connect(user='root', password='', host='127.0.0.1', database='mydb') try: cursor = cnx.cursor() cursor.execute(""" select * from dummy_data """) %timeit result_mysql = [item[0] for item in cursor.fetchall()] finally: cnx.close()
测试结果:552 ns ± 26.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
从有限实验来看,MySQL方案性能最优,但我的大部分处理操作仍依赖NumPy和Pandas函数,不确定先将数据缓存到MySQL再转入NumPy/Pandas是否合理。想请教:除性能提升外,使用MySQL数据库缓存数据还有哪些优势?
除了测试中体现的性能优势,用MySQL作为缓存层还有这些实用价值:
多进程/多实例共享数据:如果你的实时处理系统是分布式或多进程架构,内存中的NumPy/Pandas数据无法直接跨进程共享,而MySQL作为独立服务,能让多个处理节点同时访问同一份缓存的秒级时序数据,无需额外开发数据同步逻辑。
数据持久化与容错:内存缓存(NumPy/Pandas)在进程崩溃或机器重启时会丢失数据,MySQL的磁盘存储能自动持久化缓存的秒级数据,即使处理流程中断,重启后可以从数据库中恢复未完成的处理节点,不会丢失中间数据。
自带数据校验与约束:可以通过MySQL的字段类型约束、非空校验等规则,在缓存阶段就过滤掉格式错误的时序数据,避免脏数据流入后续的NumPy/Pandas处理环节,减少数据清洗的工作量。
灵活的查询能力:如果后续需要对缓存的秒级数据做临时查询(比如回溯某一秒的异常数据),MySQL的SQL语法支持复杂的过滤、聚合查询,比直接操作内存数组/DataFrame更灵活,尤其是在需要跨多个秒级批次查询时。
资源隔离:实时处理过程中,数据处理逻辑(依赖NumPy/Pandas)可能会占用大量CPU或内存,将缓存层放在MySQL中,可以把内存资源更多留给计算逻辑,避免缓存数据挤占计算资源,提升整体系统的稳定性。
不过需要注意:你的测试只测了数据读取的耗时,实际场景中还要考虑将秒级数据写入MySQL的开销,以及从MySQL导出到NumPy/Pandas的转换成本,建议补充这两部分的性能测试,再做最终决策。
内容的提问来源于stack exchange,提问作者Sheldon

