我已经阅读了一些csv vs数据库争论,并且在很多人中推荐了csv上的数据库解决方案。 然而,它从来没有完全相同的设置。
所以这是设置。 - 每小时生成大约50个csv文件,代表来自大约100个主机的性能组 - 每个表演组有20到100个计数器 - 我需要提取数据以创建许多预定义报告(例如,每天用于某些计数器和节点) - 这应该是相对静态的 - 我需要根据需要(例如用于调查目的)基于可变时间段,主机,计数器提取数据 - 总共每天约100MB(在所有50个文件中)
可能的解决方案?
1)将其保存在csv中 - 要为每个性能组创建主csv文件,每小时只需附加最新的csv文件 使用带有shell命令的脚本生成我的报告(grep,sed,cut,awk)
2)将其加载到数据库(例如MySQL) - 创建镜像性能组的表并将这些csv文件加载到表中 使用sql查询生成报告
当我尝试模拟并在csv文件上使用shell命令时它非常快。 我担心数据库查询会更慢(考虑到数据量)。 我也知道数据库不喜欢太宽的表 - 在我的场景中,在某些情况下我需要100多列。 它只会在大部分时间内被读取(仅附加新文件)。 我想保留一年的数据,因此大约36GB。数据库解决方案是否仍然可以正常运行(1-2核VM,预期2-4GB内存)。 我没有模拟数据库解决方案,这就是为什么我想问你是否有类似场景的观点/经验。
答案 0 :(得分:0)
我建议将其保留为 CSV (CSV)格式-要为每个性能组并每隔一个小时创建一个主csv文件,只需附加最新的csv文件即可。并仅使用 PANDAS 脚本来生成报告。
从csv加载的时间 1.7427544593811035 sec vs从数据库获取时间 53.455329179763794秒(提高31倍)
>>>
>>> from django.db.models import Prefetch, F, Value
>>> from stats.models import Rank
>>> from django.db.models.functions import Concat
>>> import pandas as pd
>>> import time
>>>
>>> rs = (Rank.objects
... .prefetch_related('stat__analyzer_proc__categories')
... .annotate(
... category=Concat(
... F('stat__analyzer_proc__categories__name'),
... Value(' '), F('stat__analyzer_proc__categories__parent__name'),
... Value(' '), F('stat__analyzer_proc__categories__parent__parent__name'),
...
... ), )
... .values_list('price', 'category')
... )[:2000000]
>>>
>>>
>>> start = time.time()
>>> print(len(rs))
2000000
>>> print(time.time() - start) # <== Time to get 2 millions rows from db
53.455329179763794
>>>
>>>
>>> start = time.time()
>>> df = pd.DataFrame(rs, columns=('price', 'category'))
>>> print(time.time() - start) # <== Time to instansiate dataframe of 2 millions rows
0.8041002750396729
>>>
>>>
>>> start = time.time()
>>> df.to_csv('/tmp/pandas_test.csv', encoding='utf-8', index=False)
>>> print(time.time() - start) # <== Time to save to csv dataframe of 2 millions rows
8.725394010543823
>>>
>>>
>>> start = time.time()
>>> df_csv = pd.read_csv('/tmp/pandas_test.csv', encoding='utf-8',)
>>> print(time.time() - start) # <== Time to load from csv dataframe of 2 millions rows
1.7427544593811035
>>>
>>>
>>> start = time.time()
>>> df_csv.groupby('category').price.agg(['mean', 'count']).sort_values(by='mean').astype(int)
>>> print(time.time() - start) # <== Time to group_by, aggregate mean, count and sort of 2 millions records
0.4874231815338135