Oracle hash分区的秘密
我在面试时经常会问一个问题,请列举出hash在数据库内部的应用,hash的原理虽然简单,但是它在数据库中可以说是无处不在。其中hash partition是hash在数据库中一个简单的应用,虽然它没有range partition那么常用,但是我们在做数据库水平拆分时,其实就是利用了hash partition的原理,利用hash函数对某个key进行运算,然后将其分布到不同的主机上,原理很简单。
我们在设计时遇到了一个问题,当分区的数量需要变化时,基于hash的原理,数据可能会从一个分区移动到另外一个分区,因为某个key在4个分区时,可能被分布在分区3,而在8个分区时,可能被分布在分区5。这样每当分区数量变化时,就需要全部重新分布数据,代价很高。
那么Oracle是怎么做的?首先可以肯定的是Oracle的hash partition在分区增加时,不需要做全部数据的重新分布。有人告诉我Oracle的hash函数比较牛,可以保证分区数量增加时,这个hash函数可以让原来的数据还在旧的分区中,而新的数据可以分布在新的分区。Oracle的函数无非就是get_hash_value或ora_hash(10g),从hash的原理上来说,这也是不可能做到的。
我们对hash partition都有一个常识,就是partition的数量最好是2的次方,也就是2,4,8,16……,否则分区会出现不分区均衡的现象,按照hash的原理,不管是几个分区,都可以做到完全均衡的,为什么会不均衡,其实答案已经出来了,Oracle为了能够增加分区,为你预留了几个看不到的分区。
假设我们有6个分区,一共8000条数据,数据的分布如下图:
hash partition不能直接增加分区,而是split当前分区,当需要增加到8个分区时,实际上是分区3和分区4分别split产生新的分区7和分区8,如下图:
Oracle如何做到分区数量增加后,其他分区的数据不受影响呢,其实很简单,Oracle在做hash运算时,预留了分区,比如6个分区,实际上是用8个分区的hash来运算的,只不过把缺少的分区的数据合并到其他分区,这样就会出现数据不均衡的情况。Oracle的公式是这样的,用等于或者大于当前分区数量的最小的一个2的N次方,比如6个分区做8个hash bucket,4个分区还是做4个hash bucket。如果要把4个分区加为5个分区,实际上把分区1 split为分区5,这时因为有5个分区了,会使用8个hash bucket。一句话总结就是hash bucket总是2的N次方,如果分区数不足,则会合并数据,产生不均衡的情况,这样增加分区时,只需要对应分区的数据做split即可。同理,减少分区也不是简单的drop,而是合并分区。
再回到我们的项目中,我们为了解决这个问题,采用了更简单的处理方案,直接就做了1024个分区,我们有8个物理数据库,每个数据库中有128个表,以后再分拆时,只要移动这些表,并修改应用中的对应关系就可以了。其实和Oracle合并再拆分的思路是一样的。
这个问题其实在大牛lewis的Practical Oracle8i中讲过,当时我并没有仔细想清楚,现在想清楚了,特此记录。有些东西,明白了就觉得它挺简单的,希望对大家有帮助。
建议继续学习:
- HashMap解决hash冲突的方法 (阅读:11326)
- 关于memcache分布式一致性hash (阅读:10714)
- MinHash原理与应用 (阅读:5933)
- LVS hash size解决4096个并发的问题 (阅读:5443)
- 无锁HashMap的原理与实现 (阅读:5464)
- 如果用户在5分钟内重复上线,就给他发警告,问如何设计? (阅读:4887)
- Ubuntu 下Hash校验和不符问题的解决 (阅读:4592)
- 分布式系统hash策略 (阅读:3777)
- redis源代码分析 - hash table (阅读:3591)
- 一致性hash算法 (阅读:3411)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:jacky 来源: Hello DBA
- 标签: hash 分区
- 发布时间:2009-12-04 13:35:43
- [70] Twitter/微博客的学习摘要
- [65] find命令的一点注意事项
- [64] 如何拿下简短的域名
- [64] IOS安全–浅谈关于IOS加固的几种方法
- [63] android 开发入门
- [62] 流程管理与用户研究
- [62] Go Reflect 性能
- [60] Oracle MTS模式下 进程地址与会话信
- [59] 读书笔记-壹百度:百度十年千倍的29条法则
- [59] 图书馆的世界纪录