Sql server Always On 读写分离配置方法

使用了Sqlserver 2012 Always on技术后,假如采用的配置是默认配置,会出现Primary server CPU很高的状况发生,好比默认配置以下:

须要自定义来解决这个问题。sql

 

咱们先来看看上图中的这些选项的意义

主角色中的链接数据库

  • 容许全部链接
    • 若是当前server是primary角色时,primary instance容许全部链接(如:读/写/管理)
  • 容许读/写链接
    • 若是当前server是primary角色时,primary instance只容许读/写链接(若是经过ssms链接,将报错、sqlcmd也是报错)

可读辅助副本windows

    • 若是当前server是primary角色时,全部的secondary servers都是能够看的(经过ssms能看结构、数据,但不能更改)
  • 仅读意向
    • 若是当前server是primary角色时,全部的secondary servers只容许读链接(须要在创建链接时加入key来标明为只读链接:ApplicationIntent=ReadOnly)
    • 若是当前server是primary角色时,全部的secondary servers都不能够看(经过ssms能链接,可是看不了,会报错,以下)

 

创建读写分离的方法:

第一种tcp

    1. 设置某具体“可用性组”的属性为:可读副本为“是”
    2. 客户端经过直连副本方式实现将select的流量转发过去
    3. 暴露出去的ip地址至少2个:侦听器ip和副本ip(若是副本多个,则可用ip哈希来进行更多的自定义)

第二种sqlserver

    1. 设置某具体“可用性组”的属性为:可读辅助副本为“仅读意向”
    1. 执行sql脚本,创建read指针
    2. 执行sql脚本,创建primary, read db ur list关系
    3. 暴露出去的ip地址只有1个:侦听器IP

 

第一种方式可以进行更多地自定义,可是已经脱离sqlserver always on技术了,所以不讨论了ui

第二种方式对于客户端来说更傻瓜点,可是自定义力度小,全依托于ms将来怎么改进这块了,并且这里有些坑。。。url

 

下面来讲说这些坑:

坑1:UI图形界面设置后,还须要执行脚原本创建读写分离支持spa

创建read指针 - 在当前的primary上为每一个sqlserver instance创建[instance name=>instance tcp url] Map3d

--因为这里有2个instance(包括了primary角色的), 所以在primary上分别为这2个instance创建关系

ALTER AVAILABILITY GROUP [alwayson]
MODIFY REPLICA ON
N'LAB-SQL1' WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'tcp://LAB-SQL1.lab-sql.com:1433'))

ALTER AVAILABILITY GROUP [alwayson]
MODIFY REPLICA ON
N'LAB-SQL2' WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'tcp://LAB-SQL2.lab-sql.com:1433'))

 

创建primary, read db ur list关系 - 在当前的primary上为各个primary创建对应的read only url 列表(有优先级概念)指针

--为每一个可能成为primary角色的server,创建相应的只读列表,下面的代码因为互为readonly server,所以优先级都是1

ALTER AVAILABILITY GROUP [alwayson]
MODIFY REPLICA ON
N'LAB-SQL2' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('LAB-SQL1')));


ALTER AVAILABILITY GROUP [alwayson]
MODIFY REPLICA ON
N'LAB-SQL1' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('LAB-SQL2')));


--假如又增长了一台lab-sql3的secdonary,则sql可变为
ALTER AVAILABILITY GROUP [alwayson]
MODIFY REPLICA ON
N'LAB-SQL2' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('LAB-SQL1', 'LAB-SQL3')));


ALTER AVAILABILITY GROUP [alwayson]
MODIFY REPLICA ON
N'LAB-SQL1' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('LAB-SQL2', 'LAB-SQL3')));

--上述语句中的列表是有优先级关系的,排在前面的具备更高的优先级

 

能够经过以下语句查看这个关系,以及相应的优先级:

select ar.replica_server_name, rl.routing_priority,
 (select ar2.replica_server_name 
 from sys.availability_read_only_routing_lists rl2 
    join sys.availability_replicas AS ar2 ON rl2.read_only_replica_id = ar2.replica_id 
where rl.replica_id=rl2.replica_id and rl.routing_priority =rl2.routing_priority 
    and rl.read_only_replica_id=rl2.read_only_replica_id) as 'read_only_replica_server_name' 
    from sys.availability_read_only_routing_lists rl join sys.availability_replicas AS ar ON rl.replica_id = ar.replica_id

这里的routing_priority就是优先级

坑2:客户端须要指定访问的数据库以及加入ReadOnly关键字

C#链接字符串

    • server=侦听器IP;database=testDB3;uid=sa;pwd=111111;ApplicationIntent=ReadOnly

SSMS方式

坑3:Hosts文件设置

因为sql server always on依赖于windows集群,而windows集群依赖于活动目录,而客户端程序所在server极可能没有加入域,所以这里的解析存在问题

因为这种读写分离的方式,其实是客户端先链接到侦听器ip,而后经过协商后,让客户端再链接到具体的副本上(用tcp url,使用了全名的,如:sql1.ad.com这种格式,在ad外部默认没法解析),所以须要修改hosts文件,为每一个可能成为read的全名增长记录,以下:

192.168.0.1        LAB-SQL1.lab-sql.com
192.168.0.2        LAB-SQL2.lab-sql.com

 

总结

  1. 简单状况下的读写分离比较适用
  2. 只适用于粗粒度的读写分离,由于增长了一个额外的ConnectionString,而不是创建在普通链接字符串上的
  3. 若是读写分离的分发规则复杂,则不适用
相关文章
相关标签/搜索