背景
须要抉择适合的计划去应答数据规模的增长,以应答逐步增长的拜访压力和数据量。
数据库的扩大形式次要包含:业务分库、主从复制,数据库分表。
数据库分表
将不同业务数据扩散存储到不同的数据库服务器,可能撑持百万甚至千万用户规模的业务,但如果业务持续倒退,同一业务的单表数据也会达到单台数据库服务器的解决瓶颈。例如,淘宝的几亿用户数据,如果全副寄存在一台数据库服务器的一张表中,必定是无奈满足性能要求的,此时就须要对单表数据进行拆分。
单表数据拆分有两种形式:垂直分表和程度分表。示意图如下:
垂直分表
垂直分表适宜将表中某些不罕用且占了大量空间的列拆分进来。
例如,后面示意图中的 nickname 和 description 字段,假如咱们是一个婚恋网站,用户在筛选其余用户的时候,次要是用 age 和 sex 两个字段进行查问,而 nickname 和 description 两个字段次要用于展现,个别不会在业务查问中用到。description 自身又比拟长,因而咱们能够将这两个字段独立到另外一张表中,这样在查问 age 和 sex 时,就能带来肯定的性能晋升。
程度分表
程度分表适宜表行数特地大的表,有的公司要求单表行数超过 5000 万就必须进行分表,这个数字能够作为参考,但并不是相对规范,要害还是要看表的拜访性能。对于一些比较复杂的表,可能超过 1000 万就要分表了;而对于一些简略的表,即便存储数据超过 1 亿行,也能够不分表。但不管怎样,当看到表的数据量达到千万级别时,作为架构师就要警惕起来,因为这很可能是架构的性能瓶颈或者隐患。程度分表相比垂直分表,会引入更多的复杂性,例如要求全局惟一的数据 id 该如何解决。
主键自增
①以最常见的用户 ID 为例,能够依照 1000000 的范畴大小进行分段,1 ~ 999999 放到表 1 中,1000000 ~ 1999999 放到表 2 中,以此类推。
②简单点:分段大小的选取。分段太小会导致切分后子表数量过多,减少保护复杂度;分段太大可能会导致单表仍然存在性能问题,个别倡议分段大小在 100 万至 2000 万之间,具体须要依据业务选取适合的分段大小。
③长处:能够随着数据的减少平滑地裁减新的表。例如,当初的用户是 100 万,如果减少到 1000 万,只须要减少新的表就能够了,原有的数据不须要动。
④毛病:散布不平均。如果依照 1000 万来进行分表,有可能某个分段理论存储的数据量只有 1 条,而另外一个分段理论存储的数据量有 1000 万条。
取模
①同样以用户 ID 为例,如果咱们一开始就布局了 10 个数据库表,能够简略地用 user_id % 10 的值来示意数据所属的数据库表编号,ID 为 985 的用户放到编号为 5 的子表中,ID 为 10086 的用户放到编号为 6 的子表中。
②简单点:初始表数量的确定。表数量太多保护比拟麻烦,表数量太少又可能导致单表性能存在问题。
③长处:表散布比拟平均。
④毛病:裁减新的表很麻烦,所有数据都要重散布。
雪花算法
雪花算法是由 Twitter 颁布的分布式主键生成算法,它可能保障不同表的主键的不重复性,以及雷同表的主键的有序性。
①核心思想:
长度共 64bit(一个 long 型)。
首先是一个符号位,1bit 标识,因为 long 根本类型在 Java 中是带符号的,最高位是符号位,负数是 0,正数是 1,所以 id 个别是负数,最高位是 0。
41bit 工夫截(毫秒级),存储的是工夫截的差值(以后工夫截 – 开始工夫截),后果约等于 69.73 年。
10bit 作为机器的 ID(5 个 bit 是数据中心,5 个 bit 的机器 ID,能够部署在 1024 个节点)。
12bit 作为毫秒内的流水号(意味着每个节点在每毫秒能够产生 4096 个 ID)。