1. 简介
在数据量不断增大的今天,单台数据库服务器无法满足应用需求,分片技术被越来越多的企业使用来扩展数据库性能和容量。在分布式环境下,如何保证分片数据的一致性、高可用与并发性是一个重要问题。
本文将介绍如何使用新技术在MSSQL环境下实现分片架构,进一步提高数据库性能与扩展性。
2. MSSQL分片实现方案
2.1. 水平分片
水平分片将按照数据的某个属性将数据分布到不同的数据库中,每个数据库承载部分数据,共同构成分片架构。基于水平分片的分布式数据库能够扩展到更大规模。
例如,我们有一个业务表student,其中的id属性是自增长的主键,我们可以将数据按照id范围分片存储到不同的数据库中,如下所示:
CREATE TABLE [dbo].[student](
[id] [int] NOT NULL,
[name] [varchar](50) NULL,
[age] [int] NULL,
CONSTRAINT [PK_student] PRIMARY KEY CLUSTERED
(
[id] ASC
)) ON [PRIMARY]
GO
-- 创建student_0数据库,并将id范围在1-1000的数据存储到student_0数据库中
CREATE DATABASE [student_0]
GO
USE [student_0]
CREATE TABLE [dbo].[student](
[id] [int] NOT NULL,
[name] [varchar](50) NULL,
[age] [int] NULL,
CONSTRAINT [PK_student] PRIMARY KEY CLUSTERED
(
[id] ASC
)) ON [PRIMARY]
GO
-- 创建student_1数据库,并将id范围在1001-2000的数据存储到student_1数据库中
CREATE DATABASE [student_1]
GO
USE [student_1]
CREATE TABLE [dbo].[student](
[id] [int] NOT NULL,
[name] [varchar](50) NULL,
[age] [int] NULL,
CONSTRAINT [PK_student] PRIMARY KEY CLUSTERED
(
[id] ASC
)) ON [PRIMARY]
GO
-- 创建student_2数据库,并将id范围在2001-3000的数据存储到student_2数据库中
CREATE DATABASE [student_2]
GO
USE [student_2]
CREATE TABLE [dbo].[student](
[id] [int] NOT NULL,
[name] [varchar](50) NULL,
[age] [int] NULL,
CONSTRAINT [PK_student] PRIMARY KEY CLUSTERED
(
[id] ASC
)) ON [PRIMARY]
GO
-- 以此类推创建更多的数据库
在应用访问时,需要根据查询条件的id范围确定需要访问哪个数据库,并对多个数据库的查询结果进行合并。
2.2. 垂直分片
垂直分片是将表中的列按照属性分散到不同的数据库中,每个数据库负责某些列的处理。通过垂直分片可以有效提高数据库IO性能和响应速度。
例如,我们有一个业务表student,包含id、name、age、address等多个属性,我们可以将id、name属性存储到一张表中,age、address属性存储到另一张表中:
-- student1表
CREATE TABLE [dbo].[student1](
[id] [int] NOT NULL,
[name] [varchar](50) NULL,
CONSTRAINT [PK_student1] PRIMARY KEY CLUSTERED
(
[id] ASC
)) ON [PRIMARY]
GO
-- student2表
CREATE TABLE [dbo].[student2](
[id] [int] NOT NULL,
[age] [int] NULL,
[address] [varchar](100) NULL,
CONSTRAINT [PK_student2] PRIMARY KEY CLUSTERED
(
[id] ASC
)) ON [PRIMARY]
GO
在应用访问时,需要对多个表的查询结果分别处理并合并。
3. 新技术实现
3.1. AlwaysOn可用性组
为了提高水平分片架构的高可用,MSSQL 2012引入了AlwaysOn可用性组,它允许将多个数据库实例组合成一个可用性组,并提供自动故障转移功能。在一个可用性组中,一个主要实例处理所有的写操作和部分的读请求,其他次要实例只用于读请求,并能够自动接管主要实例的工作。
例如,我们有两个数据库实例参与水平分片,通过可用性组将两个实例组合成一个高可用的集群:
-- 创建student_0数据库,并将id范围在1-1000的数据存储到student_0数据库中
CREATE DATABASE [student_0]
GO
USE [student_0]
CREATE TABLE [dbo].[student](
[id] [int] NOT NULL,
[name] [varchar](50) NULL,
[age] [int] NULL,
CONSTRAINT [PK_student] PRIMARY KEY CLUSTERED
(
[id] ASC
)) ON [PRIMARY]
GO
-- 在当前实例上创建可用性组
ALTER AVAILABILITY GROUP [ag_student]
ADD DATABASE [student_0]
GO
-- 创建student_1数据库,并将id范围在1001-2000的数据存储到student_1数据库中
CREATE DATABASE [student_1]
GO
USE [student_1]
CREATE TABLE [dbo].[student](
[id] [int] NOT NULL,
[name] [varchar](50) NULL,
[age] [int] NULL,
CONSTRAINT [PK_student] PRIMARY KEY CLUSTERED
(
[id] ASC
)) ON [PRIMARY]
GO
-- 在另一个实例上创建可用性组
ALTER AVAILABILITY GROUP [ag_student]
ADD DATABASE [student_1]
GO
3.2. In-Memory OLTP
为了提高垂直分片架构的性能,MSSQL 2014引入了In-Memory OLTP技术,可以将表数据存储在内存中,避免了存储在磁盘上的磁盘IO操作,从而大大提高了查询和更新速度。
例如,我们可以创建一个基于内存的表来存储age、address属性:
-- 创建内存优化的student2表
CREATE TABLE [dbo].[student2](
[id] [int] NOT NULL,
[age] [int] NOT NULL,
[address] [nvarchar](256) NOT NULL,
CONSTRAINT [PK_student2] PRIMARY KEY NONCLUSTERED HASH
(
[id]
)WITH (BUCKET_COUNT=1000000)
)WITH (MEMORY_OPTIMIZED=ON)
GO
4. 总结
水平、垂直分片加上AlwaysOn可用性组和In-Memory OLTP技术的应用,可以达到提高数据库性能、容量和高可用的目的。在企业应用中,分库分表的方案是一种重要的数据处理模式。