Today in some discussions with my colleagues we were looking at the AlwaysOn Listener which allows SQL Server client applications to be abstracted from the details of the AlwaysOn Availability Group implementation. On the surface, The Listener essentially is a cluster resource pair – a Virtual IP and a Virtual Network Name. But on deeper examination, there are some details which are worth knowing. This blog post will help you discover those!
Firstly, here is an example of how the Listener looks like in the Cluster Management. You can see the network name resource (mylisten) and the virtual IP as well (192.168.1.78.)
And in Management Studio, you can see the same details as well:
In many diagrams the Listener is shown as a separate entity, distinct from the SQL database engine. In some ways this is correct, as you might interpret from the above virtual IP and network name. However, we have to consider the endpoint as well. If you think deeply, the question which might come up in your mind is, fine, this is a network name and a virtual IP; the cluster service helps ‘online’ these on the active node (it actually ‘brings online’ the virtual IP by registering it against the network interface of the active node) – but where is the listener port being bound and listened on? The cluster service cannot do that for us.
So here’s how you can investigate the actual mechanism. Firstly, do a netstat –ano on the primary replica (which is where the listener is active) and find out which process is listening on the listener’s IP and port. In our case these dummy address and port values are 192.168.1.78 and 1433 respectively. On checking, we see:
Proto Local Address Foreign Address State PID
TCP 192.168.1.78:1433 0.0.0.0:0 LISTENING 1232
The PID 1232 is actually the PID of sqlservr.exe! That means the listener functions are actually also implemented in the database engine. FYI, here is how we can check which process is PID 1232:
C:>tasklist /fi "pid eq 1232"
Image Name PID Session Name Session# Mem Usage
========================= ======== ================ =========== ============
sqlservr.exe 1232 Services 0 227,208 K
So this means that the 'listener’ endpoint is actually being bound to inside of SQL database engine! We can confirm this easily by looking at the SQL Server errorlog:
2012-09-12 03:40:14.820 spid17s The availability group database "salesdb" is changing roles ....
2012-09-12 03:40:14.830 Server Server is listening on [ 192.168.1.78 <ipv4> 1433].
2012-09-12 03:40:14.830 Server Started listening on virtual network name 'mylisten'. No user action is required.
So this is good information – the listener actually ‘lives’ inside the sqlservr.exe of the primary replica. So any connection from the client will first reach this SQL instance and then potentially be redirected to the secondary read-only replica (if configured, which it is in my case.)
To test this, I ran a NetMon with a filter on the TCP ports for the listener (1433) and the replicas (1450). From this trace, it is obvious that there is an initial connection to the primary replica (which is actually the listener endpoint), and then the client is ‘redirected' and reconnects to the actual secondary read-only replica:
In the above NetMon trace, 192.168.1.78 is the listener IP (which is actually bound to the primary replica’s node) and you will see initially a set of login and TDS packets flowing to and from the workstation to this listener. At the end of the TDS exchange, you will see that the client on SQLWORKSTN has picked up the 192.168.1.101 (which is the secondary replica instance in my test setup) and is talking to the secondary replica.
So to summarize:
- The listener IP is physically registered on the bublic network interface of the active node which hosts the AG listener cluster resource
- The cluster resource DLL for AlwaysOn (hadrres.dll) communicates with the primary replica SQL instance
- The primary replica in turns binds to the listener IP and port
- The read-write client which connects to the listener is actually directly connected, without any additional overhead
- Read-only clients may be redirected (depending on the configuration, which is indeed the case in my testing above)
- This redirection needs support from the client library, which is implemented in .NET 4.5 and SQL Client 2012 respectively (links below)
Some additional reading on this subject:
- SqlClient Support for High Availability, Disaster Recovery
- SQL Server Native Client Support for High Availability, Disaster
- sqlcmd Utility (check this for the –K ReadOnly parameter.)
I hope this gives you a deeper insight how the AG Listener connectivity works. If you enjoyed reading this as much as I enjoyed creating this walkthrough, please take a minute and leave a comment and rate this post!