S哥:今天去面试啦,简历上写了一句“熟练运用算法于应用中”,面试官问我时,却不知道说啥(很尴尬)......
ME:可以说说 hash 算法,先说说分库分表;然后一致性 hash;然后升华......
年底了,确实有很多默默看机会的盆友,开始躁动了起来。身边很多选手也不例外,身边的 S 哥为了彰显自己牛掰,简历上斗胆撂了一句“熟练运用算法于应用中”,但是当面试官问起时,S 哥却被问的一愣一愣哒。
鉴于此,不妨分享一下我的回答思路,看能否帮你争取点面试分。
先说一个离我们比较近的应用场景。估计多数人还没有经历过分库分表,但是个人感觉,截止到目前稍微有点量级的应用,数据库可能没有拆分,但是订单表应该也被拆分的稀碎啦,这么说你可能不理解,不妨举个栗子。
起初,原有的一张 T_ORDER 足矣满足业务需求,但是随着业务推广,订单表的数据日益增多,数据查询势必会越来越慢,性能是个问题。好的解决方案势必是分开,例如分成 T_ORDER_0、T_ORDER_1、T_ORDER_2 三张滚动表,但是到底该怎么实现这么个策略呢?
码代码的不写点代码,确实不是那么回事儿!
上面的代码来自于实际应用,可能代码不雅观,但是线上跑的却很好,所以也无心修理它。但是无论怎么跑,结果总会是 T_ORDER_0、T_ORDER_1、T_ORDER_2 来回切换。
好了,知道了如何分表了,但是如果数据量依旧很大,是不是应该考虑分库啦,不多说,直接摘实际应用中一个较全的代码进行示意。
针对上面代码,咱们稍微抽象一点的去说一下(这块需要顿悟,尤其是数学不太好,脑子空间不够的同学,不妨拿个铅笔,算一算)。
抽象正式开始啦,若有 M 个数据库主节点,数据表总计拆分成 N 张子表,拆表字段数值化转换为 X,则数据库实例的序号为 X % M ;数据表的序号为 X % N。
例如:当主节点个数 M=6,总计拆表数 N=1200 时(单库内子表个数为 200),则数据库实例的序号 X % 6;数据表的序号为 X % 1200。
于是:序号为 0 的数据库中,会有序号为 0,6,12,18… 的数据表;序号为 1 的数据库中,会有序号为 1,7,13,19… 的数据表;以此类推。
拆表字段数值化机制:取拆表依据字段,对其取 crc32,之后取绝对值,即为上述“分库分表公式”中的 X。
好了,到这距离咱们研发最近的 hash 算法就聊明白了,到这估计面试官也被你搞懵啦!
但是面试中经常会谈及一致性 hash,到底要聊的是个啥呢?Memcached 里面用到了吗?Nginx 里面用到了吗?MapReduce 里面用到了吗?数据倾斜又是怎么回事呢?
未完待续,且听下回分解。