JonLv 的个人博客   记录精彩的程序人生

Open Source, Open Mind,
Open Sight, Open Future!

ClickHouse TOO_MANY_PARTS 异常分析与优化实践 有更新!

线上出现 TOO_MANY_PARTS 异常,初步排查未发现调用量激增或 ClickHouse 负载过高。深入分析发现,因 本地表未进行分区 ,所有数据存储在同一大分区内,导致大量小分片生成,影响合并效率。

关键原因

  1. 未定义 PARTITION BY ,导致所有数据集中在单个分区。
  2. 单笔插入 ,每条数据都会生成一个小分片,加剧分片数量问题。

解决方案

  • 显式定义分区键 (如按时间分区)优化数据存储。
  • 改为批量插入 ,减少小分片数量,提高合并效率。
  • 优化分片键和索引 ,提升整体查询和存储性能。

ArrayList 扩容相关思考

本文针对 Java ArrayList 源码中的三个常见疑问展开分析:

1. 减法比较 vs 直接比较

grow() 方法中使用 newCapacity - MAX_ARRAY_SIZE > 0 而非直接比较,是为了处理整数溢出的极端情况。

  • 直接比较 :若 newCapacity 溢出为负数(如扩容过大),会错误跳过容量校验逻辑。
  • 减法比较 :溢出后的结果可能触发 hugeCapacity() 方法,通过检查 minCapacity 是否溢出(负数)抛出 OutOfMemoryError,确保异常情况被捕获。

2. MAX_ARRAY_SIZE 设为 Integer.MAX_VALUE - 8 的原因

  • 预留元数据空间 :避免因 JVM 对象头(类型指针、数组长度等)占用内存导致分配失败。
  • 兼容性保障 :不同 JVM 实现可能对数组元数据有不同要求,预留 8 字节增强通用性。
  • 极端突破机制hugeCapacity() 方法仍允许在安全条件下分配至 Integer.MAX_VALUE,平衡安全性与灵活性。

3. modCount 的作用与 Fail-Fast 机制

  • 功能 :记录集合结构性修改次数(如增删元素),用于迭代时检测并发修改。
  • 实现原理 :迭代器保存初始 expectedModCount,每次操作前校验与 modCount 是否一致,不一致则抛出 ConcurrentModificationException
  • 应用场景 :防止单线程迭代时误改集合,或暴露多线程并发修改问题,辅助开发者快速定位逻辑错误。

核心总结 :通过源码级分析,揭示了 ArrayList 在容量计算、内存分配安全边界及并发修改检测中的设计权衡,体现了 Java 集合框架对稳定性、兼容性和异常处理的细致考量。

记一次 Clickhouse 数据写入成功,但是却无数据问题

在一次数据排查中发现 ClickHouse 存在数据丢失现象。通过代码、日志分析排除了程序问题,并进一步发现问题出在 ReplicatedReplacingMergeTree 存储引擎。表的 ORDER BY 组合键中部分字段值可能导致多条数据被错误聚合,尤其是在高并发场景下。

具体原因是 order_no 字段部分数据存储了外部时间戳,导致字段值重复,触发了 ClickHouse 的数据聚合机制。验证后发现,若修改某个字段值,数据可正常插入。

解决方案 :在 ORDER BY 中新增 id 列,确保每条数据唯一,从而避免数据被错误聚合。

记一次mybatis与mybatisplus及mysql与cilickhouse共存遇到的问题 有更新!

在维护一个老项目时,考虑引入Mybatis-plus作为持久层,但在使用easy-code生成模板信息后遇到了Invalid bound statement异常。解决方案包括修改XML路径及实体别名映射配置,手动设置SqlSessionFactory为MybatisSqlSessionFactoryBean,并注意设置主键ID的生成方式。

同时,由于项目涉及日志记录,需要对日志存储进行改造,将后续日志请求落库到Clickhouse中。为此,进行了Clickhouse数据源和MySQL数据源的配置,使用Mybatis-plus增强的MybatisSqlSessionFactoryBean,同时集成分页插件。整体改造涉及持久层、数据源配置和日志存储,以适应项目的新需求和技术栈更新。

记一次 MQ 消费失败引发的一系列问题

本文通过一个真实的案例,揭示了在分布式系统中排查问题时,看似诡异的现象背后往往隐藏着简单的原因。在排查 Pulsar 消息消费异常问题时,作者通过仔细对比日志和数据库记录,最终发现问题根源在于环境混淆。这个案例提醒我们,在排查问题时,要保持怀疑精神,全面考虑各种可能性,避免被表面现象所迷惑。

记一次 Zookeeper 高负载引发的一系列问题 有更新!

在一次系统中,Zookeeper (ZK) 突然出现高负载,导致Provider和Consumer与ZK的连接异常,尽管系统一直提示连接异常,服务之间的调用却依然正常。通过排查和分析,发现ZK的高负载与连接超时导致的异常有关,但需要进一步探讨为什么即使ZK连接异常,Dubbo服务间的调用仍然正常,以及ZK高负载的根因。

记一次分布式 ID 主键冲突问题

在一次UAT环境测试中,发现了主键冲突问题,原因是UAT和Prod共用相同的数据库,但Zookeeper配置的Host不同。分布式ID生成器在不同环境下生成了相同的ID,导致冲突。这种问题在项目初期可能出现,但随着Prod环境自增值的增加,冲突应会减少。然而,由于运维在一次故障排查中清理了生产ZK的缓存,导致自增序列重置,冲突问题再次出现。为避免类似问题,建议在分布式ID生成算法中引入更多唯一元素,如更长的时间戳、机器码和序列号,参考雪花算法,以确保ID的唯一性。

记一次maven推送jar问题 有更新!

在使用Maven命令 mvn deploy:deploy-file 部署Jar包时,出现了两种异常:

  1. Return code is: 401, ReasonPhrase: Unauthorized

    • 需要检查 settings.xml 文件中配置的账号是否正确且有部署权限,同时确保 -DrepositoryId 配置在配置文件中存在对应ID。
  2. Return code is: 405, ReasonPhrase: PUT

    • 需要检查 -Durl 是否合法。此问题是由于URL不正确导致。通过IDEA进行部署没有问题,但使用该命令无法推送。修改URL后可以正常推送。

问题分析:

  • settings.xml 中配置的URL: http://git.hstypay.com:8081/repository/maven-public//maven-releases/
  • 命令中使用的URL: http://git.hstypay.com:8081/repository/maven-releases/

尽管URL中只多了“maven-public”,但这导致了部署异常。目前尚未找到原因。

一文讲清加解签名、加解密、数字签名、数字证书 有更新!

本文通过一个虚构的故事,生动地展示了通信安全的重要性及其潜在风险。故事中的二毛和鹰酱在与大毛的对抗中,由于通信安全漏洞导致了信息被截获和篡改,进而引出了加密通信的必要性。文章详细介绍了对称加密、非对称加密和不可逆加密等基础概念,并探讨了不同加密方法的优缺点。通过逐步分析,从明文传输、对称加密、非对称加密,到引入数字证书和HTTPS协议,最终提出了一种安全可靠的加密通信设计方案,以保障信息在传输过程中的机密性和完整性。本文为读者提供了一个清晰的安全加密设计流程,并强调了实际应用中各类加密技术的综合使用。

记一次Druid连接池关闭异常问题 有更新!

文章描述了在一个项目中引入ClickHouse数据库后出现的异常情况,具体表现为Bean注销异常和数据连接获取失败异常。通过排查发现问题根源是MySQL和ClickHouse两个数据源设置了相同的name属性,导致在销毁连接池时发生错误。解决方法是让数据源自动生成name属性,避免重名导致连接池关闭的问题。文章总结了在配置多数据源时需要小心连接池配置,尤其是对于name属性的设置。

记公司出口网关建设遇到问题 有更新!

Tplinker项目的创建是因为公司需要统一外部导出服务器并监视和管理出站请求以确保安全性。该项目有两种模式:透明模式和非透明模式,适用于不同的场景。然而,在开发和巩固历史导出URL的过程中,出现了一些问题,例如由于在URL中使用outgoing-gateway值导致的签名错误、由X-Forwarded-For头引起的403权限问题以及由于服务器在读取流时发送的无效分块响应而导致的无响应问题。本文提供了解决这些问题的方法,例如使用原始URL进行签名生成以及禁用proxy_set_header X-Forwarded-For配置。