一、SCAN 概念

SCAN(Single Client Access Name)是 Oracle从11g R2开始推出的,客户端可以通过 SCAN 特性负载均衡地连接到 RAC数据库

SCAN 最明显的优点就是,当集群中新增加了节点或者删除了节点,不需要额外维护客户端

查看 SCAN 的配置信息的方式如下:

[grid@rac2 ~]$ srvctl config scan
SCAN name: rac-scan, Network: 1/192.168.56.0/255.255.255.0/bond0
SCAN VIP name: scan1, IP: /rac-scan/192.168.56.90

查看 SCAN VIP 的状态:可以发现 SCAN VIP 运行在节点 rac2

[grid@rac2 ~]$ srvctl status scan
SCAN VIP scan1 is enabled
SCAN VIP scan1 is running on node rac2

二、IP 概念

RAC 中有很多种 IP,每种 IP 的作用分别是什么呢?

Public IP:

  • 这是网卡上配置的真实IP地址,我们称为公共IP,这个IP的存在关系到 VIP 能不能正确漂在其所在网卡上
  • 注意,PUBLIC IP是不提供给客户端去连接配置的,这并不是说通过 PUBLIC IP 无法连接实例,而是当节点服务器宕机时,所有向它请求连接的客户端都会有等待现象并且最后得到超时信息

Private IP:

  • 称为私网 IP(私有IP),它是用于心跳同步的,也就是保证两台服务器数据同步
  • Oracle另一个高可用性连接特性(HAIP)
  • 其实 Cache Fusion 会消耗节点服务器很大的私网资源,另外,私网间无法通信还会引起 brain split(脑裂),以前为解决这种问题,我们可以采用网卡 bonding 技术,而 Oracle 在 11g R2 的时候通过 HAIP 技术来实现
  • HAIP(Highly Available Virtual IP)用于节点间的私网通信,支持同时使用多个网络连接来满足网卡间的负载均衡,并且还提高了Cache Fusion 资源通信能力

Virtual IP:

  • RAC 的每个节点都需要有一个虚拟IP,这就是VIP
  • VIP 会绑定到节点的 public 网卡上,需要和 PUBLIC IP同一个子网,它们是由 GI 的 Clusterware 来管理的
  • VIP 在其节点服务器发生故障的时候会自动漂移到另外正常的节点服务器上,如果 RAC 是多节点运行的,那具体漂移到哪个活动的节点将由Clusterware 决定
  • 等故障节点恢复正常,漂移的 VIP 也回到此节点上,继续提供服务

三、监听概念

下面再解释一下 RAC 中监听的概念

LOCAL LISTENER:

  • 本地监听,RAC 的每个节点上都会有独立的本地监听,它会监听该节点的 PUBLIC IP和VIP
  • 每个节点的实例在启动的时候向本地监听进行注册,当 VIP 或者PUBLIC IP (这种情况比较少见)有连接请求的时候,本地监听就接受处理并和本地实例建立连接。如果某个节点故障,其上面的VIP会进行漂移,但本地监听并不会产生漂移

SCAN LISTENER:

  • SCAN 监听,它是实现 SCAN 负载均衡的原理所在
  • SCAN 监听跟着 SCAN VIP 随机分配到节点服务器上,如果某个节点发生故障,运行在此节点上的 SCAN VIP 会进行漂移,这时候 SCAN 监听也跟着漂移到正常的节点上,继续为 SCAN VIP 监听连接请求,当 PMON 进程下次动态更新实例信息到该 SCAN 监听后,它又重新接受客户端的连接

查看 SCAN 监听的配置和状态:

[grid@rac2 ~]$ srvctl config scan_listener
SCAN Listener LISTENER_SCAN1 exists. Port: TCP:1521 [grid@rac2 ~]$ srvctl status scan_listener
SCAN Listener LISTENER_SCAN1 is enabled
SCAN listener LISTENER_SCAN1 is running on node rac2

1、local_listener 参数

该参数控制着本地监听的注册,通过本地监听的数据库连接请求只会连接到本地节点的实例上

数据库中,该参数设置为向本地 VIP 地址进行注册:

SQL> show parameter local

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
local_listener string (ADDRESS=(PROTOCOL=TCP)(HOST=
192.168.56.80)(PORT=1521))

查看本地监听的状态,可以发现本地监听在 Public IP 和 VIP 上监听,只监听本地实例:

[grid@rac2 ~]$ lsnrctl status listener

Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.20)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.80)(PORT=1521)))
Services Summary...
Service "+ASM" has 1 instance(s).
Instance "+ASM2", status READY, has 1 handler(s) for this service...
Service "rac" has 1 instance(s).
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "racXDB" has 1 instance(s).
Instance "rac2", status READY, has 1 handler(s) for this service...

2、remote_listener 参数

该参数控制 SCAN 监听的注册,每个节点上都设置,这样的话,每个节点的 PMON 都会向 SCAN 监听注册实例信息,所以 SCAN监听能够负载均衡地分发连接请求到节点本地监听上,也就是连接到其本地节点实例上

示例:

SQL> show parameter remote_listener 

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
remote_listener string rac-scan:1521

查看 SCAN 监听的状态,可以发现它监听了所有实例:

[grid@rac2 ~]$ lsnrctl status listener_scan1

Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER_SCAN1)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.90)(PORT=1521)))
Services Summary...
Service "rac" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "racXDB" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...

3、修改 remote_listener 参数

通过 remote_listener的修改,让 SCAN 以及所有节点的本地监听都可以监听到所有数据库实例

第一步,在节点 rac1 的 tnsnames.ora文件中配置 tnsnames,使该节点可以被 rac2 的 listener 监听到:

[oracle@rac1 admin]$ pwd
/u01/app/oracle/product/11.2.0/db_1/network/admin [oracle@rac1 admin]$ vim tnsnames.ora
RAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = rac)
)
)

在节点 rac2 的 tnsnames.ora文件中配置 tnsnames,使该节点可以被 rac1 的 listener 监听到:

RAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = rac)
)
)

第二步,修改 remote_listener 参数(在其中一个节点操作即可):


SQL> alter system set remote_listener=rac; System altered.

第三步,查看 LISTENER 监听状态,可以监控到所有的数据库实例

[grid@rac1 admin]$ lsnrctl status

Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.10)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.60)(PORT=1521)))
Services Summary...
Service "+ASM" has 1 instance(s).
Instance "+ASM1", status READY, has 1 handler(s) for this service...
Service "rac" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "racXDB" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...

第四步,查看 SCAN 监听状态,可以监控到所有的数据库实例(需要先查看 SCAN 监听在哪个节点)

[grid@rac1 ~]$ lsnrctl status listener_scan1

Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER_SCAN1)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.90)(PORT=1521)))
Services Summary...
Service "rac" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "racXDB" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...

详解 RAC 中各种IP和监听的意义的更多相关文章

  1. (转)详解Linux中SSH远程访问控制

    详解Linux中SSH远程访问控制 原文:http://blog.51cto.com/dengqi/1260038 SSH:是一种安全通道协议,主要用来实现字符界面的远程登录,远程复制等功能(使用TC ...

  2. 详解nodejs中使用socket的私聊和公聊的办法

    详解nodejs中使用socket的私聊和公聊的办法 nodejs的应用中,关于socket应该是比较出彩的了,socket.io在github上有几万人的star,它的成功应该是不输于express ...

  3. 详解Vue中的computed和watch

    作者:小土豆 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.cn/user/2436173500265335 1. 前言 作为一名Vue ...

  4. jQuery:详解jQuery中的事件(二)

    上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...

  5. 图文详解Unity3D中Material的Tiling和Offset是怎么回事

    图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...

  6. 【转】详解C#中的反射

    原帖链接点这里:详解C#中的反射   反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...

  7. 详解Webwork中Action 调用的方法

    详解Webwork中Action 调用的方法 从三方面介绍webwork action调用相关知识: 1.Webwork 获取和包装 web 参数 2.这部分框架类关系 3.DefaultAction ...

  8. 【转】详解JavaScript中的this

    ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...

  9. 深入详解SQL中的Null

    深入详解SQL中的Null NULL 在计算机和编程世界中表示的是未知,不确定.虽然中文翻译为 “空”, 但此空(null)非彼空(empty). Null表示的是一种未知状态,未来状态,比如小明兜里 ...

随机推荐

  1. day_1 练习2

    #!/usr/bin/env python# -*- coding:utf-8 -*-'''b. 功能要求: v = 2000 要求用户输入总资产,例如:2000 显示商品列表,让用户根据序号选择商品 ...

  2. C#文件下载(适用于各个浏览器)

    1.cs代码 public void DownFile(string filePath ,string fileName ) { // filePath 文件路径 例如:/File/记录.xlsx / ...

  3. java泛型探索——小特性

    泛型特性(小篇幅) 1. 补充介绍一些常见的泛型特性: 类型参数T可以是recursive(类似递归性),它的边界可以是类型参数是自身的接口或类. 如我实现寻找最大值的方法,可以这么写: public ...

  4. 添加本地jar包到本地的Maven仓库以及在Maven仓库中搜索想要添加的jar包

    今天在学习Memacached的时候,将java_memcached-release下载下来,要使用maven来集成相关的jar包,Memcached的jar包如下: java_memcached-r ...

  5. 关于微信小程序的Request请求错误处理

    在学微信小程序的request请求的时候,一开始报“不在以下合法域名列表中,请参考文”的错误,后来又莫名其妙的报“400 Bad Request”错误,经过半天的研究,终于搞定了,把遇到的错误给大家分 ...

  6. CentOS6.5下netcat工具安装教程

    1.下载下载地址:http://sourceforge.net/projects/netcat/files/netcat/0.7.1/下载的是netcat-0.7.1.tar.gz版本 2.拷贝用U盘 ...

  7. 【JAVAWEB学习笔记】03_JavaScript

    javascript简单介绍 ECMAScript 1.语法 2.变量:只能使用var定义,如果在函数的内容使用var定义,那么它是一个局部变量,如果没有使用var它是一个全局的.弱类型! 3.数据类 ...

  8. 原生JS Ajax 请求

    var username = document.getElementById('username').value; var password = document.getElementById('pa ...

  9. DropDownList如何绑定DataTable,如何绑定DataSet

    dpDnUpMenu是我定义的DropDownList控件 如果直接使用下面的方式,则会出现如下错误 dpDnUpMenu.DataSource = menu_tbBll.GetPID() dpDnU ...

  10. VS2013各版本激活密钥

    Visual Studio Ultimate 2013 KEY(密钥):BWG7X-J98B3-W34RT-33B3R-JVYW9 Visual Studio Premium 2013 KEY(密钥) ...