• 若干设计经验教训小记


    前瞻性思考###

    缘由

    新系统重构中,收获了一个重要的设计教训。

    事情是这样滴,如下图所示:

    有一个 Hbase 表 oe_item 存放订单商品相关的交易信息,rowkey 设计为 “订单号_oldItemID” ,是通过 storm 同步任务处理 old_item 表的binlog订阅写入该表的。oe_item 的量级很大。

    在老的实现方式中,由于应用在访问这个表之前无法取到订单的oldItemID, 因此,需要拿到订单号去 scan 这个表。显然这个开销是很大的。当需要访问大量订单的 oe_item 数据时,并发访问这个表会导致超时,线程被hang住,进而影响系统整体稳定性。若有可能,应该干掉 scan oe_item 这个威胁系统稳定性的耗时操作。

    系统重构后,通过详情API接口,能够获取到新订单及newItemID, 能够获取到老订单及oldItemId。显然,对于老订单来说,可以用{order_no}_{oldItemID}拼成 rowkey 来 batchGet oe_item 表; 然而,对于新订单,由于无法获取到oldItemID, 这使得要获取新订单 oe_item 表的信息,依然要 scan 这个表,而不能替换为 batchGet, —— 众所周知, batchGet 操作通常比 scan 操作的性能要更好,获取大数据量时稳定性更优 , —— 因此,错过了优化系统稳定性的一个关键环节。是不是很蛋疼 ?

    教训

    1. 要敏锐地主动发现旧设计的一些过时之处。即使当时不能解决,也应记录下来,当机会来临时进行重构优化。
    2. 在新系统重构中,及时用新设计来取代和兼容老设计。在这个例子中,如果在系统重构中,将 rowkey 设计为 新订单 -> "{order_no}{newItemID}",老订单 -> "{order_no}{oldItemID}",就可以用 batchGet 取代 scan ,大幅提升系统在获取大数据量时的稳定性。

    根本性解决方案###

    在没有对整体设计足够清晰之前,不要急于着手去解决一个问题。 仓促地解决一个问题,会导致解决不足,继续受到该问题的困扰,之前的方案甚至会造成束缚。

    敏捷设计并不是不做充分的思考和设计,而是强调不要“过犹不及”; 完成当前需要的,并为扩展预留空间。 这实际上需要更充分的设计考量。

    比如做订单导出配置化时,我是采用小步优化逼近的方式来实现配置能力的。这固然也能解决问题,但是当面对新问题时,时而有某个地方考虑不周到,需要再修改代码和发布。 这即是因为在整体设计上没有思考的足够清晰,没有足够的融会贯通, 以致于总是纰漏百出。

    因此,解决问题,要从整体设计上尽量考量得足够清晰,然后再下手去做。

    不要兼容老方案###

    这里说的是,当建立新模型时,不要去兼容老方案,否则永远都没法摆脱历史包袱。

    比如做新退款信息获取的时候,当时贪急求快(也考虑到退款金额不对导致订单状态不对,会诱导商家误发货), 就沿用老方案的存储,将新退款的数据也存储在老的退款 HBase 表里, 结果新老退款都需要去 scan 这个表,性能开销甚大,而且对稳定性有影响。

    正确的做法应该是, 针对新模型,建立新方案的存储,然后在应用中聚合两种方案,分流,冷却老方案的存储和获取,一段时间后,就会自动切换到新方案上,摆脱老方案的历史包袱。

    建立良好约定###

    约定胜于配置。 良好的约定,可以使得系统的交互和整合更加简洁清晰, 而不需要考虑过多的情况,导致复杂度上升。

    比如导出扩展字段时,约定扩展字段在下单表里的存储形式,然后导出按照这种约定去获取相应数据。 除非下单存储有误,否则导出是不会有问题的,省了很多事。

    首尾呼应###

    在设计存储的时候,就要想到如何去使用。

    Think Deeper, Design Better.

  • 相关阅读:
    tiptop之4gl调试3/31
    打印空白3/31
    佛陀教育入门
    什么是佛教
    智、觉
    保持头脑清醒的窍门2/13
    php中将数组转换为指定符号分割的字符串
    kali下apche配置多网站
    php数组指定字段排序
    php 语句块耗时性能测试
  • 原文地址:https://www.cnblogs.com/lovesqcc/p/9266071.html
Copyright © 2020-2023  润新知