极客油画

把日志数据以parquet格式存放到s3对象存储,查询使用polars,在如下场景可以取代clickhouse:

  • 成本敏感且数据量巨大:你需要以最低的成本存储和查询TB甚至PB级的日志历史数据,进行审计、合规性检查或全量趋势分析
  • 分析模式灵活多变:你的查询需求不固定,经常需要执行一次性的、探索性的临时分析,Polars强大的表达能力和灵活的Schema非常适合此场景
  • 追求极简运维:你希望避免维护一个分布式数据库集群的复杂性,更倾向于使用无状态的计算服务搭配对象存储

如果决定采用 Polars + S3 的方案,以下几点建议可以帮助你获得最佳体验:

  • 数据分区是关键:按照时间(如year/month/day)甚至业务标签(如region/service)对S3上的Parquet文件进行分区,可以极大提升查询效率,Polars可以借助这些分区信息快速跳过无关数据
  • 启用Polars的流式引擎:对于超大规模数据的聚合查询,在collect时使用engine='streaming'参数,可以有效突破内存限制,实现平滑处理
  • 优化Parquet文件:避免产生大量小文件。在数据写入阶段,将小文件合并成大小适中(如100MB-1GB)的Parquet文件,这不仅能提升查询性能,也能节省S3存储成本

parquet文件

存算分离: 计算用polars,存储用s3,文件格式用parquet。

parquet文件就是用来存冷数据的,热数据请放到postgresql里面,并定期将postgresql中的冷数据转成parquet文件后迁移到s3,或者将s3中的热数据转到postgresql中来。

parquet + polars,全文检索的时候,比较慢怎么办,又不想使用elasticSearch这类增加数据冗余的方案

class ProductionParquetSearcher:
    """生产环境Parquet全文检索优化方案"""
    
    def __init__(self, data_path: str):
        self.data_path = Path(data_path)
        
        # 1. 元数据缓存
        self.metadata_cache = self.load_metadata()
        
        # 2. 布隆过滤器索引
        self.bloom_index = self.load_bloom_index()
        
        # 3. 热点数据缓存
        self.hot_cache = TTLCache(maxsize=1000, ttl=300)
        
    def search(self, query: str, use_index: bool = True):
        # 第一步:快速过滤
        if use_index and query in self.bloom_index:
            # 第二步:索引定位
            candidate_files = self.locate_via_index(query)
            
            # 第三步:并行精确搜索
            with ThreadPoolExecutor() as executor:
                results = list(executor.map(
                    lambda f: self.exact_search_in_file(f, query),
                    candidate_files
                ))
            
            return pl.concat([r for r in results if r is not None])
        
        # 后备:全扫描
        return self.full_scan(query)
    
    def exact_search_in_file(self, file_path: Path, query: str):
        """单个文件的精确搜索(流式)"""
        return (
            pl.scan_parquet(file_path)
            .filter(pl.col("content").str.contains(query))
            .collect(streaming=True)  # 流式避免内存问题
        )

关键建议

  • 先测量再优化:用 pl.Config监控查询性能
  • 分层存储:热数据放内存,温数据建索引,冷数据全扫描
  • 不要过早优化:先确认瓶颈在哪里

本文发表于 0001-01-01,最后修改于 0001-01-01。

本站永久域名「 jiavvc.top 」,也可搜索「 极客油画 」找到我。


上一篇 « 下一篇 »

赞赏支持

请我吃鸡腿 =^_^=

i ysf

云闪付

i wechat

微信

推荐阅读

Big Image