一、缓存
缓存如memcached,redis,这里讨论redis,也有redis和leveldb结合的持久化数据库。
优化:
a.
pipeline模式,批量执行命令,提高redis的执行效率,减少内存使用。
b. shard redis时,用
consistent hash均匀分布数据。输入机器列表,存取时,算法根据数据id_key算出value在哪台机器上。
shard redis,最简单方法是对一个id取模,比如我有4个redis的db,通过对id模4,得出数据应该放到1,2,3,4哪个db上。
1. 增加一个db时,模4变模5,id5之前在db1,
现在在db5,id10之前在db2,现在在db5。db5上查找id缓存失败,就去实际数据库取一份放到db5上。db1上缓存的部分数据过期作废,相应的db2、3、4相应放到db5上的缓存也会过期作废。几乎所有数据受到影响。
2
. 一个db挂掉的情况,比如db4,这时只好取模3,所有db4的数据都命中不到,只好新建一份放到db1、2、3上面。
3. 使用consistent hash,每次增加或者减少一个db,受到影响的只是hash环上此db节点到上一个db节点之间的数据[
http://blog.chinaunix.net/uid-9162199-id-4080168.html]。consistent hash受影响的数据就仅仅是一个db node的数据。
二、数据库
RDBMS有postgresql,oracle;nosql有mongodb,cassandra,hbase;索引的有solr,elastic search。
mongodb 分collection过多,就会报错,A 16 megabyte namespace file can support approximately 24,000 namespaces. Each collection and index is a namespace. 所以一个id对应一个collection的方案理论上无法满足超过24000的id数量。
能否采用起若干个mongodb进程,对每个id路由找到相应的mongodb进程端口,然后取模20000(20000个collections),把相应id存储在相应db的相应collection上?
可以。那么对id路由到相应mongodb怎么做?
制作一个路由表,对于每个id应该如何路由清楚的记录下来。路由表既可以通过二叉平衡树(略复杂的算法),又可以通过hash桶的方式,而且这个路由表要求稳定,不能出单点故障,加写锁(写时既不可以写,也不可以读)。
路由表可以通过consistent hash的方法做吗?
不可以。为何?
因为取模或者consistent hash是使用来命中缓存的,但用在数据库路由上,哈哈,让我们来分析一下。
新加入一个mongodb机器或进程,对id取模时,以前一个mongodb里的数据现在模到了新mongodb上,以前的数据就丢了;做consistent hash时,会有部分hash环上数据命中到新的数据库,这部分数据也丢了。所以consistent hash对于数据库shard来说,不可靠。
分库:
先建立512个数据库(mongodb里面的db,pg里面的database),当一台机器撑不住的时候,再开第二台,这时把第一台机器里面的1~256的数据库不动,257~512的数据库迁移到第二台机器上,同时要做数据库的路由表。当机器添加到4台时,把数据库分成1~128,129~256,257~384,385~512,迁移数据库到相应机器。
阅读(2138) | 评论(0) | 转发(2) |