MXS-2555 Add SmartRouter documentation
This commit is contained in:
parent
f4e04f5c42
commit
3cb05813a0
@ -66,11 +66,12 @@ of their use.
|
||||
|
||||
- [Avrorouter](Routers/Avrorouter.md)
|
||||
- [Binlogrouter](Routers/Binlogrouter.md)
|
||||
- [Cat](Routers/Cat.md)
|
||||
- [HintRouter](Routers/HintRouter.md)
|
||||
- [Read Connection Router](Routers/ReadConnRoute.md)
|
||||
- [Read Write Split](Routers/ReadWriteSplit.md)
|
||||
- [Schemarouter](Routers/SchemaRouter.md)
|
||||
- [Cat](Routers/Cat.md)
|
||||
- [SmartRouter](Routers/SmartRouter.md)
|
||||
|
||||
The legacy diagnostic routing module MaxAdmin has been deprecated: avoid using
|
||||
it.
|
||||
|
229
Documentation/Routers/SmartRouter.md
Normal file
229
Documentation/Routers/SmartRouter.md
Normal file
@ -0,0 +1,229 @@
|
||||
# SmartRouter
|
||||
|
||||
[TOC]
|
||||
|
||||
## Overview
|
||||
|
||||
SmartRouter is the query router of the SmartQuery framework. Based on the type
|
||||
of the query, each query is routed to the server or cluster that can best
|
||||
handle it.
|
||||
|
||||
For workloads where both transactional and analytical queries are needed,
|
||||
SmartRouter unites the Transactional (OLTP) and Analytical (OLAP) workloads into
|
||||
a single entry point in MaxScale. This allows a MaxScale client to freely mix
|
||||
transactional and analytical queries using the same connection. This is known
|
||||
as Hybrid Transactional and Analytical Processing, HTAP.
|
||||
|
||||
## Configuration
|
||||
|
||||
SmartRouter is configured as a service that either routes to other MaxScale
|
||||
routers or plain servers. Although one can configure SmartRouter to use a plain
|
||||
server directly, we refer to the configured "servers" as clusters.
|
||||
|
||||
For details about the standard service parameters, refer to the
|
||||
[Configuration Guide](../Getting-Started/Configuration-Guide.md).
|
||||
|
||||
### `master`
|
||||
|
||||
One of the clusters must be designated as the **`master`**. All writes go to the
|
||||
master cluster, which for all practical purposes should be a master-slave
|
||||
ReadWriteSplit. This document does not go into details about setting up
|
||||
master-slave clusters, but suffice to say, that when setting up the ColumnStore
|
||||
servers they should be configured to be slaves of a MariaDB server running an
|
||||
InnoDB engine. The ReadWriteSplit [documentation](ReadWriteSplit.md) has more on
|
||||
master-slave setup.
|
||||
|
||||
### Service as a Server
|
||||
|
||||
Currently the configuration for a router (service) can have a number of servers,
|
||||
but not other routers (services). Suppose you have a cluster of servers that are
|
||||
managed by ReadWriteSplit. In order for that cluster to be routed-to by
|
||||
SmartRouter, the service must be exposed as a server. A server section in the
|
||||
configuration file that exposes a service instead of defining an actual server,
|
||||
is known as *Service as a Server*.
|
||||
|
||||
#### Example
|
||||
|
||||

|
||||
|
||||
Suppose we have a service like
|
||||
```
|
||||
[RWS-Row]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
```
|
||||
for which we have defined the listener
|
||||
```
|
||||
[RWS-Row-Listener]
|
||||
type=listener
|
||||
service=RWS-Row
|
||||
socket=/tmp/rws-row.sock
|
||||
```
|
||||
That is, that service can be accessed using the socket `/tmp/rws-row.sock`.
|
||||
|
||||
A server section that would expose that service as a server, looks like this:
|
||||
```
|
||||
[RWS-Row-as-a-server]
|
||||
type=server
|
||||
socket=/tmp/rws-row.sock
|
||||
```
|
||||
Assuming we have defined `RWS-Column`, `RWS-Column-Listener` and
|
||||
`RWS-Column-as-a-server` similarly, we can define the SmartQuery
|
||||
service as follows:
|
||||
```
|
||||
[SmartQuery]
|
||||
type = service
|
||||
router = smartrouter
|
||||
servers = RWS-Row-as-a-server, RWS-Column-as-a-server
|
||||
master = RWS-Row-as-a-server
|
||||
user = <user>
|
||||
password = <password>
|
||||
|
||||
[SmartQuery-Listener]
|
||||
type = listener
|
||||
service = SmartQuery
|
||||
protocol = mariadbclient
|
||||
port = <port>
|
||||
```
|
||||
Note that the SmartQuery listener listens on a port, while the Service as a Server
|
||||
listeners listen on a Unix domain socket. The reason is that there is a significant
|
||||
performance benefit when SmartRouter accesses the services over a Unix domain socket
|
||||
compared to accessing them over a TCP/IP socket.
|
||||
|
||||
Note that RWS-Row-as-a-server is designated as the master.
|
||||
|
||||
The RWS-Row-as-a-server looks like this:
|
||||
```
|
||||
[RWS-Row-Listener]
|
||||
type = listener
|
||||
service = RWS-Row
|
||||
protocol = mariadbclient
|
||||
socket = /tmp/rws-row.sock
|
||||
|
||||
[RWS-Row-as-a-server]
|
||||
type = server
|
||||
socket = /tmp/rws-row.sock
|
||||
protocol = MariaDBBackend
|
||||
```
|
||||
A complete configuration example can be found at the end of this document.
|
||||
|
||||
## Cluster selection - how queries are routed
|
||||
|
||||
SmartRouter keeps track of the performance, or the execution time, of queries to
|
||||
the clusters. Measurements are stored with the canonical of a query as the key.
|
||||
The canonical of a query is the sql with all user-defined constants replaced with
|
||||
question marks. When SmartRouter sees a read-query whose canonical has not been
|
||||
seen before, it will send the query to all clusters. The first response from a
|
||||
cluster will designate that cluster as the best one for that canonical. Also,
|
||||
when the first response is received, the other queries are cancelled. The
|
||||
response is sent to the client once all clusters have responded to the query
|
||||
or the cancel.
|
||||
|
||||
There is obviously overhead when a new canonical is seen. This means that
|
||||
queries after a MaxScale start will be slightly slower than normal. The
|
||||
execution time of a query depends on the database engine, and on the contents
|
||||
of the tables being queried. As a result, MaxScale will periodically re-measure
|
||||
queries.
|
||||
|
||||
The performance behavior of queries under dynamic conditions, and their effect
|
||||
on different storage engines is being studied at MariaDB. As we learn more, we
|
||||
will be able to better categorize queries and move that knowledge into
|
||||
SmartRouter.
|
||||
|
||||
## Limitations
|
||||
|
||||
* `LOAD DATA LOCAL INFILE` is not supported.
|
||||
* The performance data is not persisted. The measurements have to be performed
|
||||
anew after each startup.
|
||||
|
||||
## Complete configuration example
|
||||
```
|
||||
[maxscale]
|
||||
|
||||
[row_server_1]
|
||||
type = server
|
||||
address = <ip>
|
||||
port = <port>
|
||||
protocol = MariaDBBackend
|
||||
|
||||
[row_server_2]
|
||||
type = server
|
||||
address = <ip>
|
||||
port = <port>
|
||||
protocol = MariaDBBackend
|
||||
|
||||
[Row-Monitor]
|
||||
type = monitor
|
||||
module = mariadbmon
|
||||
servers = row_server_1, row_server_2
|
||||
user = <user>
|
||||
password = <password>
|
||||
monitor_interval = 2000ms
|
||||
|
||||
[column_server_1]
|
||||
type = server
|
||||
address = <ip>
|
||||
port = <port>
|
||||
protocol = MariaDBBackend
|
||||
|
||||
[Column-Monitor]
|
||||
type = monitor
|
||||
module = csmon
|
||||
servers = column_server_1
|
||||
user = <user>
|
||||
password = <password>
|
||||
monitor_interval = 2000ms
|
||||
|
||||
# Row Read write split
|
||||
[RWS-Row]
|
||||
type = service
|
||||
router = readwritesplit
|
||||
servers = row_server_1, row_server_2
|
||||
user = <user>
|
||||
password = <password>
|
||||
|
||||
[RWS-Row-Listener]
|
||||
type = listener
|
||||
service = RWS-Row
|
||||
protocol = mariadbclient
|
||||
socket = /tmp/rws-row.sock
|
||||
|
||||
# Columnstore Read write split
|
||||
[RWS-Column]
|
||||
type = service
|
||||
router = readwritesplit
|
||||
servers = column_server_1
|
||||
user = <user>
|
||||
password = <password>
|
||||
|
||||
[RWS-Column-Listener]
|
||||
type = listener
|
||||
service = RWS-Column
|
||||
protocol = mariadbclient
|
||||
socket = /tmp/rws-col.sock
|
||||
|
||||
[RWS-Row-as-a-server]
|
||||
type = server
|
||||
socket = /tmp/rws-row.sock
|
||||
protocol = MariaDBBackend
|
||||
|
||||
[RWS-Column-as-a-server]
|
||||
type = server
|
||||
socket = /tmp/rws-col.sock
|
||||
protocol = MariaDBBackend
|
||||
|
||||
# Smart Query router
|
||||
[SmartQuery]
|
||||
type = service
|
||||
router = smartrouter
|
||||
servers = RWS-Row-as-a-server, RWS-Column-as-a-server
|
||||
master = RWS-Row-as-a-server
|
||||
user = <user>
|
||||
password = <password>
|
||||
|
||||
[SmartQuery-Listener]
|
||||
type = listener
|
||||
service = SmartQuery
|
||||
protocol = mariadbclient
|
||||
port = <port>
|
||||
```
|
BIN
Documentation/Routers/images/sr-config.png
Normal file
BIN
Documentation/Routers/images/sr-config.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
x
Reference in New Issue
Block a user