MySQL Partitioning

Posted: Tháng Tám 20, 2021 in Database, mariadb, mysql
Thẻ:, ,

I. About mysql partitioning

1. About

Partition là việc chia dữ liệu từ table đơn với một tệp dữ liệu vật lý thành nhiều phần khác và được lưu trữ trong các tệp dữ liệu vật lý khác nhau.

Một số ưu điểm của partition

  • Cho phép lưu được nhiều dữ liệu hơn vào một table khi partition khi so sánh với việc lưu trữ dữ liệu table vào một tệp tin hoặc một disk đơn. Nghĩa là dữ liệu partition có thể lưu trữ ở nhiều disk vật lý khác nhau.

  • Việc query có thể tối ưu hơn khi thực hiện query dữ liệu trên một hoặc một vài partition thay vì phải query toàn bộ dữ liệu table.

Một số hạn chế của partition

Một số cấu trúc sau không được sử dụng trong partition:

  • Stored procedures, stored functions, UDFs, or plugins

  • Declared variables or user variables

Toán tử số học và logic:

  • Toán tử +, – , * được phép sử dụng trong partition tuy nhiên kết quả phải là integer hoặc NULL (ngoại trừ sử dụng kiểu KEY partitioning).

  • Toán tử DIV được hỗ trợ nhưng toán tử / không được phép.

  • Các toán tử |, &, ^, <<, >>, and ~ không được phép sử dụng trong các biểu thức partition.

Query cache không được hỗ trợ trong partition

2. Partition types

  • Range partition: Loại partition này sẽ phân các row thành các partition với phạm vi (range) được định nghĩa.

  • List partition: Phân các row thành các partition dựa trên các column đúng với một trong một tập giá trị rời rạc

  • Hash partition: Mỗi partition trong kiểu hash dựa trên giá trị được trả về bởi một biểu thức do người dùng định nghĩa.

  • Key partition: Kiểu partition này giống với hash partition, ngoại trừ việc chỉ cung cấp một hoặc nhiều column được đánh giá và MySQL server cung cấp hàm hash riêng của nó.

II. How to create partitions

1. How to add partitions to a table in mariadb / mysql

Thực hiện tạo cấu trúc bảng và đồng thời tạo partitions như sau:

CREATE TABLE `crm_realtime` (
  `id` varchar(200) NOT NULL,
  `name` varchar(200) DEFAULT NULL,
  `status` int(11) DEFAULT '0',
  `type` int(11) DEFAULT '0',
  `user_id` int(11) DEFAULT NULL,
  `registed_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `sales_team1` (`sales_team`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE COLUMNS (registed_at) (
  PARTITION p0 VALUES LESS THAN ('2020-04-01'),
  PARTITION p1 VALUES LESS THAN ('2020-05-01'),
  PARTITION p2 VALUES LESS THAN ('2020-06-01'),
  PARTITION p3 VALUES LESS THAN ('2020-07-01'),
  PARTITION p4 VALUES LESS THAN ('2020-08-01'),
  PARTITION p5 VALUES LESS THAN ('2020-09-01'),
  PARTITION p6 VALUES LESS THAN ('2020-10-01'),
  PARTITION p7 VALUES LESS THAN ('2020-11-01'),
  PARTITION p8 VALUES LESS THAN ('2020-12-01'),
  PARTITION p9 VALUES LESS THAN ('2021-01-01'),
  PARTITION p10 VALUES LESS THAN ('2021-02-01'),
  PARTITION p11 VALUES LESS THAN ('2021-03-01'),
  PARTITION p12 VALUES LESS THAN (MAXVALUE)
);

2. How to add partitions to an existing table in mariadb / mysql

Chẳng hạn một bảng có cấu trúc dữ liệu như sau:

CREATE TABLE `crm_realtime` (
  `id` varchar(200) NOT NULL,
  `name` varchar(200) DEFAULT NULL,
  `status` int(11) DEFAULT '0',
  `type` int(11) DEFAULT '0',
  `user_id` int(11) DEFAULT NULL,
  `registed_at` datetime DEFAULT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `sales_team1` (`sales_team`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Khi table này crm_realtime phình to ra, chúng ta có thể thực hiện chia bảng thành nhiều partitions để cho phép thực hiện query nhanh hơn.

Nếu tạo partition với range từng month theo trường registed_at kiểu datetime, yêu cầu các bước sau:

    1. Cập nhật các giá trị NULL của registed_at row đến các giá trị NOT NULL
    1. Thiết lập registed_at field là NOT NULL
    1. Thiết lập registed_at field là PRIMARY KEY
    1. Thực hiện alter bảng và tạo các partitions với type RANGE và dùng function COLUMN cho kiểu dữ liệu datetime (hoặc function UNIX_TIMESTAMP với kiểu dữ liệu timestamp)

Chúng ta thực hiện cụ thể như sau:

mysql>use crm;
mysql>update table crm_realtime set registed_at = updated_at where registed_at is NULL;
mysql>alter table crm_realtime modify column registed_at datetime NOT NULL;
mysql>alter table crm_realtime drop PRIMARY KEY, add primary key (`id`, `registed_at`);
msyql>alter table crm_realtime
PARTITION BY RANGE COLUMNS (registed_at) (
  PARTITION p202003 VALUES LESS THAN ('2020-04-01'),
  PARTITION p202004 VALUES LESS THAN ('2020-05-01'),
  PARTITION p202005 VALUES LESS THAN ('2020-06-01'),
  PARTITION p202006 VALUES LESS THAN ('2020-07-01'),
  PARTITION p202007 VALUES LESS THAN ('2020-08-01'),
  PARTITION p202008 VALUES LESS THAN ('2020-09-01'),
  PARTITION p202009 VALUES LESS THAN ('2020-10-01'),
  PARTITION p202010 VALUES LESS THAN ('2020-11-01'),
  PARTITION p202011 VALUES LESS THAN ('2020-12-01'),
  PARTITION p202012 VALUES LESS THAN ('2021-01-01'),
  PARTITION p202101 VALUES LESS THAN ('2021-02-01'),
  PARTITION p202102 VALUES LESS THAN ('2021-03-01')
);

III. Partition Management

  • Show thông tin các partition của crm_realtime table
SELECT PARTITION_NAME, TABLE_ROWS FROM  INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='crm_realtime';
+----------------+------------+
| PARTITION_NAME | TABLE_ROWS |
+----------------+------------+
| p202003        |      45495 |
| p202004        |      61398 |
| p202005        |      22573 |
| p202006        |      23146 |
| p202007        |      28804 |
| p202008        |      34576 |
| p202009        |      34566 |
| p202010        |      59116 |
| p202011        |      67070 |
| p202012        |      85030 |
| p202101        |      86926 |
| p202102        |      56797 |

or

SHOW CREATE TABLE crm_realtime\G

or

EXPLAIN SELECT * FROM crm_realtime\G

  • Thêm mới partition từ table đã có sẵn các partitions
mysql> ALTER TABLE crm_realtime ADD PARTITION (
    -> PARTITION p202103 VALUES LESS THAN ('2021-04-01')
    -> );
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0
  • Thay đổi tên partition

Thông tin việc tạo các partition nên để theo quy tắc nhất định để cho phép select dữ liệu ở một hoặc một số partition dễ dàng hơn. Chẳng hạn select dữ liệu theo mẫu pYYMM chẳng hạn.

mysql>
ALTER TABLE crm_realtime REORGANIZE PARTITION p1 INTO ( PARTITION p202003 VALUES LESS THAN ('2020-04-01') );
ALTER TABLE crm_realtime REORGANIZE PARTITION p2 INTO ( PARTITION p202004 VALUES LESS THAN ('2020-05-01') );
ALTER TABLE crm_realtime REORGANIZE PARTITION p3 INTO ( PARTITION p202005 VALUES LESS THAN ('2020-06-01') );
ALTER TABLE crm_realtime REORGANIZE PARTITION p4 INTO ( PARTITION p202006 VALUES LESS THAN ('2020-07-01') );
ALTER TABLE crm_realtime REORGANIZE PARTITION p5 INTO ( PARTITION p202007 VALUES LESS THAN ('2020-08-01') );
ALTER TABLE crm_realtime REORGANIZE PARTITION p6 INTO ( PARTITION p202008 VALUES LESS THAN ('2020-09-01') );
  • Remove partition without delete data

ALTER TABLE table-name REMOVE PARTITIONING;

IV. How to use

  • Show thông tin dữ liệu trong một partition được chỉ định
mysql> select id,name,registed_at from crm_realtime partition(p202103) limit 2;
+------------+------+---------------------+
| id         | name | registed_at         |
+------------+------+---------------------+
| 1000000009 | abc  | 2021-03-10 02:00:41 |
| 1000101010 | def  | 2021-03-12 02:00:58 |
+------------+------+---------------------+
2 rows in set (0.00 sec)

  • Show thông tin dữ liệu trong một số partition
mysql> select id,name,registed_at from crm_realtime partition(p202102,p202103) limit 5;
+------------+--------------------+---------------------+
| id         | name               | registed_at         |
+------------+--------------------+---------------------+
| 083878492  | nguyen van A       | 2021-02-20 10:43:33 |
| 1000010000 | nguyen van B       | 2021-02-19 02:00:32 |
| 1009944888 | nguyen van C       | 2021-02-26 02:01:02 |
| 1011239922 | nguyen van D       | 2021-02-17 16:58:04 |
| 1033355978 | nguyen van E       | 2021-02-01 20:06:27 |
+------------+--------------------+---------------------+
5 rows in set (0.01 sec)

  • Xóa dữ liệu trong partition
mysql> delete from crm_realtime partition(p202104) where name = "keepwalking";
Query OK, 1 row affected (0.00 sec)

NOTE

  • Việc đánh partition table làm cho table phân thành nhiều mảnh vật lý. Việc query cũng sẽ lựa chọn một hoặc một số partition tùy thuộc vào nhu cầu. Và query cả table (không sử dụng partition) dữ liệu vẫn toàn vẹn.

See more >> https://dev.mysql.com/doc/refman/5.7/en/partitioning.html

I. Requirements

Old Servers

  • 192.168.1.11 port 30001,30002
  • 192.168.1.12 port 30001,30002
  • 192.168.1.13 port 30001,30002

New Servers

  • 192.168.1.31 port 30001,30002
  • 192.168.1.32 port 30001,30002
  • 192.168.1.33 port 30001,30002

II. Deployments

Các bước chuyển từ Redis cluster đến hệ thống mới redis cluster mới.

  • Trong qúa trình start redis cluster, yêu cầu turn off AppendOnlyFile(.aof)

Step1: Dump data trên từng old redis servers (master instances)

Thực hiện dump all redis instances với chế độ BGSAVE, tức là quá trình hệ thống cũ vẫn hoạt động bình thường

/opt/redis/src/redis-cli -h 192.168.1.11 -p 30001
192.168.1.11:30001>BGSAVE
/opt/redis/src/redis-cli -h 192.168.1.12 -p 30001
192.168.1.12:30001>BGSAVE
/opt/redis/src/redis-cli -h 192.168.1.13 -p 30001
192.168.1.13:30001>BGSAVE
/opt/redis/src/redis-cli -h 192.168.1.11 -p 30002
192.168.1.11:30002>BGSAVE
/opt/redis/src/redis-cli -h 192.168.1.12 -p 30002
192.168.1.12:30002>BGSAVE
/opt/redis/src/redis-cli -h 192.168.1.13 -p 30002
192.168.1.13:30002>BGSAVE

Step2: Cài đặt Redis cluster trên 03 nodes với cấu hình appendonly=no

  • Copy bộ cài redis-5.0.6 lên 03 nodes vào thư mục /opt/redis
  • Start redis trên 03 nodes
cd /opt/redis/utils/create-cluster
./create-cluster start

Kiểm tra thông tin các instance xem:

[root@db1 create-cluster]# ../../src/redis-cli -h 192.168.1.31 -p 30001 info replication
# Replication
role:master
connected_slaves:0
master_replid:5836d772e7e0fbcb7807a2264569f0a8fd1fba8f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
[root@db1 create-cluster]# ../../src/redis-cli -h 192.168.1.31 -p 30002 info replication
# Replication
role:master
connected_slaves:0
master_replid:816fabe2746344b099c7c5510af35490f938fb8c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

Lúc này chúng ta thấy instance vẫn là các host độc lập, đều ở role là master.

  • Create cluster trên node01
cd /opt/redis/utils/create-cluster
./create-cluster create
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.1.32:30002 to 192.168.1.31:30001
Adding replica 192.168.1.33:30002 to 192.168.1.32:30001
Adding replica 192.168.1.31:30002 to 192.168.1.33:30001
M: 696af2c06bf2e02ec12ec78d102f3a16c55f8732 192.168.1.31:30001
   slots:[0-5460] (5461 slots) master
M: e911dffb0ac4e4f58da3a43a82a2ca33cf27933e 192.168.1.32:30001
   slots:[5461-10922] (5462 slots) master
M: 0802d3965bad300a5bdba071fa881aa856691600 192.168.1.33:30001
   slots:[10923-16383] (5461 slots) master
S: 515809a113cc52bb260c37d37b6ffbee0b86795f 192.168.1.31:30002
   replicates 0802d3965bad300a5bdba071fa881aa856691600
S: 52a9915d2fbf300f7167ebca8c2a396b62879756 192.168.1.32:30002
   replicates 696af2c06bf2e02ec12ec78d102f3a16c55f8732
S: 389437d7f5dcd71734ec4e78fada5d2af21b57c4 192.168.1.33:30002
   replicates e911dffb0ac4e4f58da3a43a82a2ca33cf27933e
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
..
>>> Performing Cluster Check (using node 192.168.1.31:30001)
M: 696af2c06bf2e02ec12ec78d102f3a16c55f8732 192.168.1.31:30001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: e911dffb0ac4e4f58da3a43a82a2ca33cf27933e 192.168.1.32:30001
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 389437d7f5dcd71734ec4e78fada5d2af21b57c4 192.168.1.33:30002
   slots: (0 slots) slave
   replicates e911dffb0ac4e4f58da3a43a82a2ca33cf27933e
M: 0802d3965bad300a5bdba071fa881aa856691600 192.168.1.33:30001
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 515809a113cc52bb260c37d37b6ffbee0b86795f 192.168.1.31:30002
   slots: (0 slots) slave
   replicates 0802d3965bad300a5bdba071fa881aa856691600
S: 52a9915d2fbf300f7167ebca8c2a396b62879756 192.168.1.32:30002
   slots: (0 slots) slave
   replicates 696af2c06bf2e02ec12ec78d102f3a16c55f8732
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Kiểm tra thông tin các instance

[root@db1 create-cluster]# ../../src/redis-cli -h 192.168.1.31 -p 30002 info replication
# Replication
role:slave
master_host:192.168.1.33
master_port:30001
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:182
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:c8da87a8e7f3568cca0e227bc106d5fc61c5d5e0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:182

Step3: Copy dump (.rdb) đến new redis servers

  • Stop redis trên 03 nodes

Thực hiện stop redis trên 03 nodes trước khi copy rdb từ old redis servers đến new redis servers

cd /opt/redis/utils/create-cluster
./create-cluster stop
  • Copy rdb từ các master redis hiện tại đến master redis mới tương ứng

On 192.168.1.11

Thực hiện copy dump files đến 192.168.1.31

scp /opt/redis/utils/create-cluster/dump-30001.rdb root@192.168.1.31:/opt/redis/utils/create-cluster/

scp /opt/redis/utils/create-cluster/dump-30001.rdb root@192.168.1.31:/opt/redis/utils/create-cluster/

On 192.168.1.12

Thực hiện copy dump files đến 192.168.1.32

scp /opt/redis/utils/create-cluster/dump-30001.rdb root@192.168.1.32:/opt/redis/utils/create-cluster/

scp /opt/redis/utils/create-cluster/dump-30001.rdb root@192.168.1.32:/opt/redis/utils/create-cluster/

On 192.168.1.13

Thực hiện copy dump files đến 192.168.1.33

scp /opt/redis/utils/create-cluster/dump-30001.rdb root@192.168.1.33:/opt/redis/utils/create-cluster/

scp /opt/redis/utils/create-cluster/dump-30001.rdb root@192.168.1.33:/opt/redis/utils/create-cluster/

Step4: Start redis on nodes

On 192.168.1.31

cd /root/redis/utils/create-cluster/
./create-cluster start

On 192.168.1.32

cd /root/redis/utils/create-cluster/
./create-cluster start

On 192.168.1.33

cd /root/redis/utils/create-cluster/
./create-cluster start

Khi các redis instance được start, nó đọc dữ liệu từ tệp dump sau đó load dữ liệu vào memory.

Step5: Enable AppendOnly (AOF)

Trong trường hợp cần cố định log write xuống disk, thực hiện enable appendonly=yes ( Trường hợp không cần thiết có thể bỏ qua bước này)

Thực hiện chạy lệnh sau trên các redis instance để enable Append Only File (AOF)

redis-cli -h 192.168.1.31 -p 30001
>config set appendonly yes

redis-cli -h 192.168.1.32 -p 30001
>config set appendonly yes

redis-cli -h 192.168.1.33 -p 30001
>config set appendonly yes

redis-cli -h 192.168.1.31 -p 30002
>config set appendonly yes

redis-cli -h 192.168.1.32 -p 30002
>config set appendonly yes

redis-cli -h 192.168.1.33 -p 30002
>config set appendonly yes

1. Requirements

  • Mô hình hệ thống

Hệ thống được triển khai trên 5 nodes, gồm 14 instances (02 instances cho mongos, 03 instances cho config server, 03 instances cho shard1, 03 instances cho shard2, 03 instances cho shard3)

  • Quy hoạch IP và port
mongodb shard cluster
  • Thêm thông tin sau vào /etc/hosts
192.168.1.111    mongo-config-1
192.168.1.112    mongo-config-2
192.168.1.113    mongo-config-3
192.168.1.11    mongos01
192.168.1.12    mongos02

2. Installing MongoDB

Thực hiện các bước sau trên các servers

Create repo

cat >/etc/yum.repos.d/mongodb.repo<<EOF
[MongoDB]
name=MongoDB Repository
baseurl=http://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.0/x86_64/
gpgcheck=0
enabled=1
EOF

Installing

yum install mongodb-org -y

3. Setup Config Server

Thực hiện cấu hình các bước sau trên các Config server

Step1: Tạo thư mục chứa data cho config server, shards

mkdir -p /data/config
mkdir -p /data/shard1
mkdir -p /data/shard2
mkdir -p /data/shard3
chown -R mongod. /data

Step2: Tạo tệp cấu hình /etc/mongod-config.conf

systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

storage:
  dbPath: /data/config
  journal:
    enabled: true

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod-config.pid  # location of pidfile
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27020
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

replication:
   replSetName: "replconfig01"

sharding:
   clusterRole: configsvr

Step3: Start mongodb configsrv

mongod --config /etc/mongod-config.conf

Step4: Configure replication on configsvr

Sau khi run các config server, chúng ta thực hiện khởi tạo replication trên một instance của config server

mongo --host localhost --port 27020
rs.initiate(
  {
    _id: "replconfig01",
    configsvr: true,
    members: [
      { _id : 0, host : "mongo-config-1:27020" },
      { _id : 1, host : "mongo-config-2:27020" },
      { _id : 2, host : "mongo-config-3:27020" }
    ]
  }
)

Note: Chúng ta khởi tạo replica set con config server với tham số cấu hình configsvr: true

4. Setup Shards

Thực hiện cấu hình các bước sau trên shard server

Ở đây, trên mỗi server chúng ta tạo 03 instance cho mongod với các port 27017,27018,27019 tương ứng cho các shard1, shard2, shard3. Nghĩa là, chúng tạo 03 shard, với mỗi shard là một replica set của 3 instances, vì thế chúng ta sẽ tạo 09 instance cho mongod service

Trên mỗi server, chúng ta thực hiện các bước sau để cấu hình các shard

Step1: Cấu hình cho shard1

  • Tạo các tệp cấu hình /etc/mongo-shard1.conf
systemLog:
  destination: file
  logAppend: true
  logRotate: reopen
  path: /var/log/mongodb/shard1.log

storage:
  dbPath: /data/shard1
  journal:
    enabled: true

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod-shard1.pid  # location of pidfile
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27017
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

replication:
   replSetName: "shard01"

sharding:
   clusterRole: shardsvr

Trong tệp cấu hình này, chúng đặt tên cho replication là “shard01” và clusterRole cho sharding là “shardsvr”.

Tương tự như vậy, chúng ta tạo tệp cấu hình cho shard2 và shard3

  • Tạo các tệp cấu hình /etc/mongo-shard2.conf
systemLog:
  destination: file
  logAppend: true
  logRotate: reopen
  path: /var/log/mongodb/shard2.log

storage:
  dbPath: /data/shard2
  journal:
    enabled: true

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod-shard2.pid  # location of pidfile
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27018
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

replication:
   replSetName: "shard02"

sharding:
   clusterRole: shardsvr
  • Tạo các tệp cấu hình /etc/mongo-shard3.conf
systemLog:
  destination: file
  logAppend: true
  logRotate: reopen
  path: /var/log/mongodb/shard3.log

storage:
  dbPath: /data/shard3
  journal:
    enabled: true

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod-shard3.pid  # location of pidfile
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27019
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

replication:
   replSetName: "shard03"

sharding:
   clusterRole: shardsvr

Step2: Start các mongod service

Thực hiện start các instance mongod service trên các server3, server4, server5

mongod --config /etc/mongo-shard1.conf
mongod --config /etc/mongo-shard2.conf
mongod --config /etc/mongo-shard3.conf

Step3: Cấu hình replica set cho các shard

Trên mỗi replica set, chúng ta sẽ ưu tiên trên mỗi server chỉ chỉ set một vai trò master trên đó để đảm bảo việc read/write dữ liệu vào các server cân bằng hơn.

  • Cấu hình replica set cho shard1

Thực hiện truy cập mongo shard và khởi tạo replica set shard1 trên server3

mongo --host localhost --port 27017
rs.initiate(
  {
    _id: "shard01",
    members: [
      { _id : 0, host : "mongo-config-1:27017", priority: 2 },
      { _id : 1, host : "mongo-config-2:27017", priority: 1 },
      { _id : 2, host : "mongo-config-3:27017", priority: 0 }
    ]
  }
)
  • Cấu hình replica set cho shard2

Thực hiện truy cập mongo shard và khởi tạo replica set shard2 trên server4

mongo --host localhost --port 27018
rs.initiate(
  {
    _id: "shard02",
    members: [
      { _id : 0, host : "mongo-config-2:27018", priority: 2 },
      { _id : 1, host : "mongo-config-3:27018", priority: 1 },
      { _id : 2, host : "mongo-config-1:27018", priority: 0 }
    ]
  }
)
  • Cấu hình replica set cho shard3

Thực hiện truy cập mongo shard và khởi tạo replica set shard3 trên server5

mongo --host localhost --port 27019
rs.initiate(
  {
    _id: "shard03",
    members: [
      { _id : 0, host : "mongo-config-3:27019", priority: 2 },
      { _id : 1, host : "mongo-config-1:27019", priority: 1 },
      { _id : 2, host : "mongo-config-2:27019", priority: 0 }
    ]
  }
)

Step4: Check shard trên mỗi server

[root@node01 ~]# mongo -port 27017
MongoDB shell version v4.0.23
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("ced31d75-f290-40dd-a54c-0c584b8e7d96") }
MongoDB server version: 4.0.23
shard01:PRIMARY> 


[root@node02 ~]# mongo --port 27018
MongoDB shell version v4.0.23
connecting to: mongodb://127.0.0.1:27018/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("6b942cd1-207f-4dc7-9ef3-526f56808a9e") }
MongoDB server version: 4.0.23
shard02:PRIMARY> 

[root@node03 ~]# mongo --port 27019
MongoDB shell version v4.0.23
connecting to: mongodb://127.0.0.1:27019/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("068a5068-57b0-4f38-9ea3-3fbbfdbc24b0") }
MongoDB server version: 4.0.23
shard03:PRIMARY> 

5. Setup Query Router ( mongos)

Phần này, chúng ta thực hiện cấu hình trên mongos instance đầu tiên.

Step1: Tệp tệp cấu hình /etc/mongod.conf

systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongos.log

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27017
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

sharding:
  configDB: "replconfig01/mongo-config-1:27020,mongo-config-2:27020,mongo-config-3:27020"

Step2: Start mongos

mongos -f /etc/mongod.conf

Nếu chạy mongos như systemd, khi đó tạo tệp tin /usr/lib/systemd/system/mongos.service

[Unit]
Description=MongoDB Database Service
Wants=network.target
After=network.target

[Service]
User=mongod
Group=mongod
Type=simple
Environment="OPTIONS=--config /etc/mongod.conf"
ExecStart=/usr/bin/mongos $OPTIONS
ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb
ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb
ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb
ExecReload=/bin/kill -HUP $MAINPID
PermissionsStartOnly=true
PIDFile=/var/run/mongodb/mongod.pid
Restart=always
Type=forking

User=mongod
Group=mongod
[Install]
WantedBy=multi-user.target
  • Start mongos service
systemctl daemon-reload
systemctl start mongos

Step3: Add shards to mongos/Query Router

Ở đây chúng ta có 03 shards với cấu hình replica set (shard01, shard02, shard03).

Login mongos

mongo --host mongos --port 27017

và thực hiện thêm các shard đến mongos như sau:

sh.addShard( "shard01/mongo-config-1:27017")
sh.addShard( "shard01/mongo-config-2:27017")
sh.addShard( "shard01/mongo-config-3:27017")

sh.addShard( "shard02/mongo-config-1:27018")
sh.addShard( "shard02/mongo-config-2:27018")
sh.addShard( "shard02/mongo-config-3:27018")

sh.addShard( "shard03/mongo-config-1:27019")
sh.addShard( "shard03/mongo-config-2:27019")
sh.addShard( "shard03/mongo-config-3:27019")
  • Check shard status
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("6077fa4c673f0ec1ec4ba9d1")
  }
  shards:
        {  "_id" : "shard01",  "host" : "shard01/mongo-config-1:27017,mongo-config-2:27017,mongo-config-3:27017",  "state" : 1 }
        {  "_id" : "shard02",  "host" : "shard02/mongo-config-1:27018,mongo-config-2:27018,mongo-config-3:27018",  "state" : 1 }
        {  "_id" : "shard03",  "host" : "shard03/mongo-config-1:27019,mongo-config-2:27019,mongo-config-3:27019",  "state" : 1 }
  active mongoses:
        "4.0.24" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }

mongos> 

Ở đây, chúng ta có thể thấy một số thông tin như thông tin các instance của các shard, trạng thái shard

Step4: Enable Sharding at Database Level

Chúng ta thử enable sharding cho một database mới

mongo --host 192.168.1.11 --port 27017
mongos> use example
switched to db example
mongos> sh.enableSharding("example")
{
    "ok" : 1,
    "operationTime" : Timestamp(1618940724, 4),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1618940724, 4),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}
mongos>

Step5: Enable Sharding at Collection Level

ở bước trên chúng ta đã enable shard cho database. Bước này chúng ta sẽ enable sharding cho một collection.

Để thực hiện sharding cho collection, chúng ta cần xác định sẽ partition theo range based hay hash based (Mặc định sharding theo range based).

Trong phần này chúng ta sẽ shard theo hash based để nhìn rõ hơn quá trình phân vùng dữ liệu qua các shard.

mongo --host 192.168.1.11 --port 27017
mongos> use example
mongos> db.exCollection.ensureIndex({ _id : "hashed" })
mongos> sh.shardCollection("example.exCollection", {"_id" : "hashed"})
mongos>

Ở đây, Chúng ta tạo collection exCollection trong example database và cần thực hiện tạo index cho trường _id với kiểu hashed. Trường _id mặc định được tạo và đánh index với unique index

Note: Việc chọn shard key ảnh hưởng cho việc tạo và phân tán chunks qua các shard có sẵn. Việc này ảnh hưởng trực tiếp đến hiệu quả và hiệu suất hoạt động trong shard cluster. Chẳng hạn với việc chọn field _id ở trên để đánh index thì chỉ có ý nghĩa về mặt phân tán dữ liệu, trong thực tế query dữ liệu hiếm khi sử dụng filter theo trường _id.

Step6: Check sharding status

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("6077fa4c673f0ec1ec4ba9d1")
  }
  shards:
        {  "_id" : "shard01",  "host" : "shard01/mongo-config-1:27017,mongo-config-2:27017,mongo-config-3:27017",  "state" : 1 }
        {  "_id" : "shard02",  "host" : "shard02/mongo-config-1:27018,mongo-config-2:27018,mongo-config-3:27018",  "state" : 1 }
        {  "_id" : "shard03",  "host" : "shard03/mongo-config-1:27019,mongo-config-2:27019,mongo-config-3:27019",  "state" : 1 }
  active mongoses:
        "4.0.24" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard01    342
                                shard02    341
                                shard03    341
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "example",  "primary" : "shard02",  "partitioned" : true,  "version" : {  "uuid" : UUID("17b43459-bb00-461a-816b-83143bdb101f"),  "lastMod" : 1 } }
                example.exCollection
                        shard key: { "_id" : "hashed" }
                        unique: false
                        balancing: true
                        chunks:
                                shard01    2
                                shard02    2
                                shard03    2
                        { "_id" : { "$minKey" : 1 } } -->> { "_id" : NumberLong("-6148914691236517204") } on : shard01 Timestamp(1, 0) 
                        { "_id" : NumberLong("-6148914691236517204") } -->> { "_id" : NumberLong("-3074457345618258602") } on : shard01 Timestamp(1, 1) 
                        { "_id" : NumberLong("-3074457345618258602") } -->> { "_id" : NumberLong(0) } on : shard02 Timestamp(1, 2) 
                        { "_id" : NumberLong(0) } -->> { "_id" : NumberLong("3074457345618258602") } on : shard02 Timestamp(1, 3) 
                        { "_id" : NumberLong("3074457345618258602") } -->> { "_id" : NumberLong("6148914691236517204") } on : shard03 Timestamp(1, 4) 
                        { "_id" : NumberLong("6148914691236517204") } -->> { "_id" : { "$maxKey" : 1 } } on : shard03 Timestamp(1, 5) 

mongos> 

Step7: Insert data và kiểm tra quá trình partition

Từ client thực hiện insert dữ liệu qua mongos

mongos>use example
mongos> for (var i = 1; i <= 10000; i++) db.exCollection.insert( { x : i } )
WriteResult({ "nInserted" : 1 })
mongos> 

Khi đó check dữ liệu phân tán ở các shard như nào

mongos> use example
mongos> db.exCollection.getShardDistribution()

Shard shard03 at shard03/mongo-config-1:27019,mongo-config-2:27019,mongo-config-3:27019
 data : 108KiB docs : 3364 chunks : 2
 estimated data per chunk : 54KiB
 estimated docs per chunk : 1682

Shard shard01 at shard01/mongo-config-1:27017,mongo-config-2:27017,mongo-config-3:27017
 data : 105KiB docs : 3263 chunks : 2
 estimated data per chunk : 52KiB
 estimated docs per chunk : 1631

Shard shard02 at shard02/mongo-config-1:27018,mongo-config-2:27018,mongo-config-3:27018
 data : 108KiB docs : 3373 chunks : 2
 estimated data per chunk : 54KiB
 estimated docs per chunk : 1686

Totals
 data : 322KiB docs : 10000 chunks : 6
 Shard shard03 contains 33.63% data, 33.63% docs in cluster, avg obj size on shard : 33B
 Shard shard01 contains 32.63% data, 32.63% docs in cluster, avg obj size on shard : 33B
 Shard shard02 contains 33.73% data, 33.73% docs in cluster, avg obj size on shard : 33B

mongos> 

6. Adding a new Query Router ( mongos)

Để hệ thống có high availability & scalability, chúng ta cần triển khai thêm mongos instance.

Về phương pháp triển khai thêm mongos instance, chúng ta chỉ cần cài đặt mongos chạy như mongos instance đầu tiên. Thông tin shard cluster nó sẽ nhận từ các Config Server.

Step1: Tệp tệp cấu hình /etc/mongod.conf

systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongos.log

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27017
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

sharding:
  configDB: "replconfig01/mongo-config-1:27020,mongo-config-2:27020,mongo-config-3:27020"

Step2: Start mongos

mongos -f /etc/mongod.conf

Nếu chạy mongos như systemd, khi đó tạo tệp tin /usr/lib/systemd/system/mongos.service

[Unit]
Description=MongoDB Database Service
Wants=network.target
After=network.target

[Service]
User=mongod
Group=mongod
Type=simple
Environment="OPTIONS=--config /etc/mongod.conf"
ExecStart=/usr/bin/mongos $OPTIONS
ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb
ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb
ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb
ExecReload=/bin/kill -HUP $MAINPID
PermissionsStartOnly=true
PIDFile=/var/run/mongodb/mongod.pid
Restart=always
Type=forking

User=mongod
Group=mongod
[Install]
WantedBy=multi-user.target
  • Start mongos service
systemctl daemon-reload
systemctl start mongos

Step3: Check shard status

  • Login mongos
[root@mongos02 ~]# mongo --host 192.168.1.12 --port 27017
MongoDB shell version v4.0.24
connecting to: mongodb://192.168.1.12:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("e415c22d-b605-4571-8cfa-c45c0d891852") }
MongoDB server version: 4.0.24
Server has startup warnings: 
2021-04-21T17:54:15.437+0000 I CONTROL  [main] 
2021-04-21T17:54:15.437+0000 I CONTROL  [main] ** WARNING: Access control is not enabled for the database.
2021-04-21T17:54:15.437+0000 I CONTROL  [main] **          Read and write access to data and configuration is unrestricted.
2021-04-21T17:54:15.437+0000 I CONTROL  [main] 
mongos> 
  • Check shard status
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("6077fa4c673f0ec1ec4ba9d1")
  }
  shards:
        {  "_id" : "shard01",  "host" : "shard01/mongo-config-1:27017,mongo-config-2:27017,mongo-config-3:27017",  "state" : 1 }
        {  "_id" : "shard02",  "host" : "shard02/mongo-config-1:27018,mongo-config-2:27018,mongo-config-3:27018",  "state" : 1 }
        {  "_id" : "shard03",  "host" : "shard03/mongo-config-1:27019,mongo-config-2:27019,mongo-config-3:27019",  "state" : 1 }
  active mongoses:
        "4.0.24" : 2
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard01    342
                                shard02    341
                                shard03    341
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "example",  "primary" : "shard02",  "partitioned" : true,  "version" : {  "uuid" : UUID("17b43459-bb00-461a-816b-83143bdb101f"),  "lastMod" : 1 } }
                example.exCollection
                        shard key: { "_id" : "hashed" }
                        unique: false
                        balancing: true
                        chunks:
                                shard01    2
                                shard02    2
                                shard03    2
                        { "_id" : { "$minKey" : 1 } } -->> { "_id" : NumberLong("-6148914691236517204") } on : shard01 Timestamp(1, 0) 
                        { "_id" : NumberLong("-6148914691236517204") } -->> { "_id" : NumberLong("-3074457345618258602") } on : shard01 Timestamp(1, 1) 
                        { "_id" : NumberLong("-3074457345618258602") } -->> { "_id" : NumberLong(0) } on : shard02 Timestamp(1, 2) 
                        { "_id" : NumberLong(0) } -->> { "_id" : NumberLong("3074457345618258602") } on : shard02 Timestamp(1, 3) 
                        { "_id" : NumberLong("3074457345618258602") } -->> { "_id" : NumberLong("6148914691236517204") } on : shard03 Timestamp(1, 4) 
                        { "_id" : NumberLong("6148914691236517204") } -->> { "_id" : { "$maxKey" : 1 } } on : shard03 Timestamp(1, 5) 

mongos> 

7. Deploy Sharded Cluster with Authentication

MongoDB hỗ trợ chứng thực giữa các member trong shard cluster với 2 phương thức

  • Keyfile
  • X.509

Trong phần này chúng sẽ cấu hình chứng thực shard cluster với keyfile và access control.

Bước 1: Tạo Keyfile

Nội dung của keyfile giống như chia sẻ mật khẩu chung giữa các member trong shard cluster. Yêu cầu độ dài của key nằm giữa 6-102 ký tự và có thể chứa các ký tự trong tập base64.

Thực hiện tạo keyfile như sau:

openssl rand -base64 123 > /var/lib/mongo/keyfile
chmod 400 /var/lib/mongo/keyfile

Thực hiện copy keyfile đã tạo ở trên đến các member server trong shard cluster. Cho rằng đường dẫn chứa keyfile mặc định của các member server là /var/lib/mongo/keyfile

Bước 2: Sửa nội dung tệp cấu hình

Thêm nội dung sau vào tệp cấu hình của các member server trong shard cluster

security:
    authorization: enabled
    keyFile: /var/lib/mongodb/keyfile

Bước 3: Start mongod và mongos

Thực hiện start các Config Server (Replica set) trước khi start các member server còn lại.

  • Start Config Servers

mongod -f /etc/mongod-config.conf

  • Start các mongod trên các server
mongod -f /etc/mongo-shard1.conf
mongod -f /etc/mongo-shard2.conf
mongod -f /etc/mongo-shard3.conf
  • Start các mongos service

systemctl start mongos

Bước 4: Tạo tài khoản quản trị

Thực hiện tạo tài khoản quản trị trên Config Server (Thực hiện trên Primary trong replconfig01)

mongo --host 192.168.1.111 --port 27020
mongo>db.createUser({user: "admin", pwd: "password", roles:[{role: "root", db: "admin"}]})

Thay thông tin admin/password với tài khoản quản trị cần thiết lập

Bước 5: Check mongo authentication

Từ client thực hiện login qua mongos

mongo --host 192.168.1.11 --authenticationDatabase admin -u admin -p
MongoDB shell version v4.0.24
Enter password: 
connecting to: mongodb://192.168.1.11:27017/?authSource=admin&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("9f244647-8560-4ea4-939b-222251d3c118") }
MongoDB server version: 4.0.24
mongos> show dbs;
admin     0.000GB
config    0.004GB
example   0.002GB
example2  0.001GB
test      0.000GB
mongos> 

Trong bài viết này, tôi tiếp tục giới thiệu thêm một sample mà cho phép client connect redis cluster và thực hiện read đến slave nodes.

Sử dụng Lettuce-core cho Java redis client để connect redis cluster

Link lettuce-core: https://github.com/lettuce-io/lettuce-core

Một số chế độ read mà Lettuce route đến Redis cluster:

Mặc định Lettuce route thao tác read đến master nodes. Lettuce-core sử dụng ReadFrom để thiết lập cách Lettuce-core route đến các nodes.

SettingDescription
MASTERDefault mode. Read from the current master node.
MASTER_PREFERREDRead from the master, but if it is unavailable, read from replica nodes.
REPLICARead from replica nodes.
REPLICA_PREFERREDRead from the replica nodes, but if none is unavailable, read from the master.
NEARESTRead from any node of the cluster with the lowest latency.

Dựa vào 5 read modes đó, chúng ta có thể chọn mode REPLICA_PREFERRED để ưu tiên read từ các slave nodes và nếu không có slave nodes thì nó sẽ read từ master nodes.

Ví dụ cấu hình kết nối redis cluster với mode read từ slave nodes

package com.keepwalking.redis;

import io.lettuce.core.ReadFrom;
import io.lettuce.core.RedisURI;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;

import java.util.Arrays;

/**
 * Hello world!
 *
 */
public class App {
    public static void main(String[] args) {
        //Connecting to Redis server on localhost
        RedisURI node1 = RedisURI.create("192.168.1.240", 30001);
        RedisURI node2 = RedisURI.create("192.168.1.240", 30002);
        RedisURI node3 = RedisURI.create("192.168.1.240", 30003);
        RedisURI node4 = RedisURI.create("192.168.1.240", 30004);
        RedisURI node5 = RedisURI.create("192.168.1.240", 30005);
        RedisURI node6 = RedisURI.create("192.168.1.240", 30006);

        RedisClusterClient clusterClient = RedisClusterClient.create(Arrays.asList(node1, node2, node3, node4, node5, node6));
        StatefulRedisClusterConnection<String, String> connection = clusterClient.connect();
        connection.setReadFrom(ReadFrom.REPLICA_PREFERRED);
        System.out.println("Connected to Redis");

        RedisAdvancedClusterCommands<String, String> sync = connection.sync();
        sync.set("hi1", "keepwalking1");
        sync.set("hi2", "keepwalking2");
        sync.set("hi3", "keepwalking3");

        sync.get("hi1"); // replica read
        sync.get("hi2"); // replica read
        sync.get("hi3"); // replica read
        //sync.get(hi2); // replica read

        connection.close();
        clusterClient.shutdown();
    }
}

Trong đó:

  • 192.168.1.240 với các ports 30001-30006 là địa chỉ các instance của redis cluster. Thay địa chỉ cụm redis cluster phù hợp với thực tế.
  • scaleReads: "all" cấu hình với chế độ read từ các slave instances.

Tôi chạy thử và set với 3 keys hi1,hi2,hi3 và get các keys tương đó.

Tham khảo mẫu tại đây: https://github.com/keepwalking86/redis-cluster/tree/master/examples/java

Trong bài viết này, tôi sẽ giới thiệu một sample đơn giản mà nodejs client sử dụng module **ioredis** kết nối với redis cluster và thực hiện read từ slave nodes.

Link ioredis: https://github.com/luin/ioredis

Một số chế độ read mà ioredis route đến Redis cluster

Mặc định ioredis route thao tác read đến master nodes. ioredis sử dụng scaleRead để thiết lập cách ioredis route đến các nodes và thiết lập thao tác read đến các nodes.

SettingDescription
AllRead queries to masters or slaves randomly.
SlaveRead queries to slaves
a customA custom function(nodes, command): node. Custom function to select to which node to send read queries

Dưới đây là một ví dụ nodejs kết nối redis với robust ioredis

var&nbsp;Redis&nbsp;=&nbsp;require("ioredis");
var&nbsp;cluster&nbsp;=&nbsp;new&nbsp;Redis.Cluster([
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;30001,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host:&nbsp;"192.168.1.240",
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;30002,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host:&nbsp;"192.168.1.240",
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;30003,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host:&nbsp;"192.168.1.240",
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;30004,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host:&nbsp;"192.168.1.240",
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;30005,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host:&nbsp;"192.168.1.240",
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;30006,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host:&nbsp;"192.168.1.240",
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;],
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;scaleReads:&nbsp;"all",
&nbsp;&nbsp;&nbsp;&nbsp;}
);

cluster.set("hi",&nbsp;"Keepwalking");
cluster.get("hi",&nbsp;function&nbsp;(err,&nbsp;res)&nbsp;{
console.log(res);
});
cluster.set("hi2",&nbsp;"Keepwalking2");
cluster.get("hi2",&nbsp;function&nbsp;(err,&nbsp;res)&nbsp;{
console.log(res);
});
cluster.set("hi3",&nbsp;"Keepwalking3");
cluster.get("hi3",&nbsp;function&nbsp;(err,&nbsp;res)&nbsp;{
console.log(res);
});
cluster.set("hi4",&nbsp;"Keepwalking4");
cluster.get("hi4",&nbsp;function&nbsp;(err,&nbsp;res)&nbsp;{
console.log(res);
});

Trong đó:

  • 192.168.1.240 với các ports 30001-30006 là địa chỉ các instance của redis cluster. Thay địa chỉ cụm redis cluster phù hợp với thực tế.
  • scaleReads: "all" cấu hình với chế độ read từ các slave instances.

Ví dụ chạy thử với set với 4 keys hi,hi2,hi3,hi4 và get các value tương ứng “keepwalking”, “keepwalking2”, “keepwalking3”, “keepwalking4”.

Login các redis slaves qua redis-cli và chạy lệnh monitor để xem kết quả read từ các slave nodes như hình dưới