{"id":2995,"date":"2025-04-23T21:59:50","date_gmt":"2025-04-23T18:59:50","guid":{"rendered":"https:\/\/www.fatihacar.com\/blog\/?p=2995"},"modified":"2025-06-01T14:18:00","modified_gmt":"2025-06-01T11:18:00","slug":"redis-7-sentinel-infrastructure-installation","status":"publish","type":"post","link":"http:\/\/www.fatihacar.com\/blog\/redis-7-sentinel-infrastructure-installation\/","title":{"rendered":"Redis 7 Sentinel Infrastructure Installation"},"content":{"rendered":"<p data-pm-slice=\"1 1 []\">Redis is an open-source, in-memory data structure store, widely used as a database, cache, and message broker. Known for its lightning-fast performance, Redis operates by keeping data in memory rather than on disk, which allows for incredibly quick read and write operations. It supports a variety of data structures such as strings, hashes, lists, sets, and sorted sets.<\/p>\n<p>One of Redis\u2019s key advantages is its support for in-memory data storage with optional durability. This means that while Redis prioritizes speed by default, it also offers mechanisms to persist data to disk in case of a crash or restart. Redis provides two primary persistence options: <strong>RDB (Redis Database Snapshotting)<\/strong> and <strong>AOF (Append Only File)<\/strong>.<\/p>\n<p>RDB creates point-in-time snapshots of your dataset at specified intervals. It is efficient in terms of I\/O and allows fast restarts, making it suitable for backup and disaster recovery. On the other hand, AOF logs every write operation received by the server, ensuring higher durability. You can configure AOF to sync to disk every second, on every command, or let the OS manage it. This flexibility allows to balance between performance and reliability.<\/p>\n<p>In many production environments, both RDB and AOF are enabled simultaneously to leverage the strengths of both methods. When both are enabled, Redis creates regular snapshots and logs every operation. This hybrid model increases data safety but also demands careful tuning of parameters to prevent excessive disk I\/O.<\/p>\n<p>Another powerful feature of Redis is its support for high availability and automatic failover through Redis Sentinel. Sentinel continuously monitors your Redis deployment to detect failures and automatically promotes a replica to master in case the primary server becomes unreachable. It also updates the configurations of other Sentinel instances and clients to reflect the new master, ensuring minimal downtime. Sentinel helps Redis maintain strong consistency and availability in distributed environments, making it an essential component in production-grade Redis clusters.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-3012\" src=\"https:\/\/www.fatihacar.com\/blog\/resimler\/redis_sentinel-1024x604.png\" alt=\"\" width=\"640\" height=\"378\" srcset=\"http:\/\/www.fatihacar.com\/blog\/resimler\/redis_sentinel-1024x604.png 1024w, http:\/\/www.fatihacar.com\/blog\/resimler\/redis_sentinel-300x177.png 300w, http:\/\/www.fatihacar.com\/blog\/resimler\/redis_sentinel-768x453.png 768w, http:\/\/www.fatihacar.com\/blog\/resimler\/redis_sentinel-850x502.png 850w, http:\/\/www.fatihacar.com\/blog\/resimler\/redis_sentinel.png 1083w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>In this article, I will mention how to set up <strong>Redis, Redis Sentinel and Keepalived<\/strong> services consisting of 1 master and 2 replica nodes in detail. I will use Redis 7.2.x version.<\/p>\n<h3>Redis Servers Information<\/h3>\n<p><b>Hostname and IP<\/b><\/p>\n<blockquote><p>Master Node : rds1 &#8211; 192.168.1.12<\/p>\n<p>Replica Node 1 : rds2 &#8211; 192.168.1.13<\/p>\n<p>Replica Node 2 : rds3 &#8211; 192.168.1.14<\/p>\n<p>Virtual Service IP &#8211; 192.168.1.11<\/p><\/blockquote>\n<h3>First Step : Configure Operating System on Each Node<\/h3>\n<p><strong>1. Upgrade Packages<\/strong><\/p>\n<blockquote><p>yum upgrade<\/p><\/blockquote>\n<p><strong>2. Selinux Disable or Permissive<\/strong><\/p>\n<blockquote><p>You can do disabled or permissive<\/p>\n<p>vi \/etc\/selinux\/config<\/p>\n<p>SELINUX=permissive<\/p>\n<p>setenforce permissive<\/p><\/blockquote>\n<p><strong>3. Firewall Close and Disable<\/strong><\/p>\n<blockquote><p>You can open after installation,but you have to give permission to necessary ports and services for Redis<\/p>\n<p>systemctl stop firewalld.service<\/p>\n<p>systemctl disable firewalld.service<\/p><\/blockquote>\n<p><strong>4. Chrony NTP Configuration<\/strong><\/p>\n<blockquote><p>You can write your ntp server information in \/etc\/chrony.conf file to time sync.<\/p>\n<p>vi \/etc\/chrony.conf<\/p>\n<p>server yourntpaddress iburst<\/p>\n<p>systemctl restart chronyd.service<\/p>\n<p>systemctl enable chronyd.service<\/p><\/blockquote>\n<p><strong>5. sysctl.conf Configuration<\/strong><\/p>\n<blockquote><p>You can add below parameters to sysctl.conf for Redis performance as your needs.<\/p>\n<p>vi \/etc\/sysctl.conf<\/p>\n<p># Redis Official<br \/>\nvm.overcommit_memory = 1 # Allows memory overcommitment, helps Redis avoid fork failures<\/p>\n<p># Redis Community Recommended<br \/>\nvm.swappiness = 1 # Controls how aggressively the kernel uses swap<br \/>\nnet.core.somaxconn = 65535 # Max connections queued before being refused<br \/>\nnet.ipv4.tcp_tw_reuse = 1 # Allows reuse of TIME-WAIT sockets for new connections<br \/>\nnet.ipv4.tcp_max_syn_backlog = 4096 # Max pending TCP connections in SYN state<br \/>\nfs.file-max = 100000 # Max number of open files allowed by the system<\/p><\/blockquote>\n<p><strong>6. limits.conf Configuration<\/strong><\/p>\n<blockquote><p>You can add below parameters to limits.conf for Redis performance as your needs.<\/p>\n<p>vi \/etc\/security\/limits.conf<\/p>\n<p># Redis Recommended Limits<br \/>\nredis soft nofile 100000<br \/>\nredis hard nofile 100000<br \/>\nredis soft nproc 65535<br \/>\nredis hard nproc 65535<br \/>\nredis soft memlock unlimited<br \/>\nredis hard memlock unlimited<\/p>\n<p>root soft nofile 100000<br \/>\nroot hard nofile 100000<br \/>\nroot soft nproc 65535<br \/>\nroot hard nproc 65535<br \/>\nroot soft memlock unlimited<br \/>\nroot hard memlock unlimited<\/p><\/blockquote>\n<p><strong>7. Disable Transparent Huge Pages<\/strong><\/p>\n<blockquote><p>Redis recommend disable transparent huge pages feature. I will create a service to disable THP.<\/p>\n<p><strong>Create service<\/strong><\/p>\n<p>vi \/etc\/systemd\/system\/disable-thp.service<\/p>\n<p>[Unit]<br \/>\nDescription=Disable Transparent Huge Pages (THP)<br \/>\nAfter=network.target<\/p>\n<p>[Service]<br \/>\nType=oneshot<br \/>\nExecStart=\/bin\/bash -c &#8220;echo never &gt; \/sys\/kernel\/mm\/transparent_hugepage\/enabled&#8221;<br \/>\nExecStartPost=\/bin\/bash -c &#8220;echo never &gt; \/sys\/kernel\/mm\/transparent_hugepage\/defrag&#8221;<br \/>\nRemainAfterExit=true<\/p>\n<p>[Install]<br \/>\nWantedBy=multi-user.target<\/p>\n<p><strong>Activate disable-thp service<\/strong><\/p>\n<p>systemctl daemon-reload<\/p>\n<p>systemctl enable disable-thp.service<\/p>\n<p>systemctl start disable-thp.service<\/p>\n<p><strong>Control THP status<\/strong><\/p>\n<p>You can check THP status with below commands. If you see as [never], THP is disable.<\/p>\n<p>cat \/sys\/kernel\/mm\/transparent_hugepage\/enabled<\/p>\n<p>cat \/sys\/kernel\/mm\/transparent_hugepage\/defrag<\/p><\/blockquote>\n<h3>Second Step : Install Redis Package on Each Node<\/h3>\n<p><strong>1. Install Redis<\/strong><\/p>\n<blockquote><p>We can install Redis with several different ways. I will use remi repo to installation. Also if you want, you can download Redis last version from redis.io by creating a account.<\/p>\n<p>Linux version is OEL 9.5. so I find suitable redis version as redis-7.2.7-1.el9.remi.x86_64.rpm<\/p>\n<p>cd \/tmp\/<\/p>\n<p>wget https:\/\/rpms.remirepo.net\/enterprise\/9.5\/modular\/x86_64\/redis-7.2.7-1.el9.remi.x86_64.rpm<\/p>\n<p>rpm -ivh redis-7.2.7-1.el9.remi.x86_64.rpm<\/p><\/blockquote>\n<p><strong>2. Create Directories<\/strong><\/p>\n<blockquote><p>I will use \/data directory for redis data directory.<\/p>\n<p>mkdir -p \/data\/redis<\/p>\n<p>chown -R redis.redis \/data<\/p><\/blockquote>\n<h3>Third Step : Configure Redis and Sentinel Configuration Files<\/h3>\n<p><strong>1. Configure redis.conf<\/strong><\/p>\n<blockquote><p>You can find redis configuration file at \/etc\/redis\/redis.conf<\/p>\n<p>I will configure below parameters. Some parameters will be different node by node.<\/p>\n<p>vi \/etc\/redis\/redis.conf<\/p>\n<p><strong>Master Node &#8211; 192.168.1.12<\/strong><\/p>\n<p>bind * -::*<br \/>\nprotected-mode no<br \/>\nloglevel verbose<br \/>\ndir \/data\/redis<br \/>\nmasterauth &#8220;Password123&#8221;<br \/>\nreplica-priority 1<br \/>\naclfile \/etc\/redis\/users.acl<br \/>\nappendonly yes<\/p>\n<p><strong>Replica Node 1 &#8211; 192.168.1.13<\/strong><\/p>\n<p>bind * -::*<br \/>\nprotected-mode no<br \/>\nloglevel verbose<br \/>\ndir \/data\/redis<br \/>\nreplicaof 192.168.1.12 6379<br \/>\nmasterauth &#8220;Password123&#8221;<br \/>\nreplica-priority 2<br \/>\naclfile \/etc\/redis\/users.acl<br \/>\nappendonly yes<\/p>\n<p><strong>Replica Node 2 &#8211; 192.168.1.14<\/strong><\/p>\n<p>bind * -::*<br \/>\nprotected-mode no<br \/>\nloglevel verbose<br \/>\ndir \/data\/redis<br \/>\nreplicaof 192.168.1.12 6379<br \/>\nmasterauth &#8220;Password123&#8221;<br \/>\nreplica-priority 3<br \/>\naclfile \/etc\/redis\/users.acl<br \/>\nappendonly yes<\/p>\n<p>chown redis.redis redis.conf<\/p><\/blockquote>\n<p><strong>2. Configure sentinel.conf<\/strong><\/p>\n<blockquote><p>You can find sentinel configuration file at \/etc\/redis\/sentinel.conf<\/p>\n<p>I will remove # for more readable file. Firstly, I will take a backup as sentinel.conf.orginal<\/p>\n<p>cd \/etc\/redis<\/p>\n<p>cp sentinel.conf sentinel.conf.orginal<\/p>\n<p>grep -Ev &#8216;^#|^$&#8217; sentinel.conf.orginal &gt; sentinel.conf<\/p>\n<p>vi sentinel.conf<\/p>\n<p><strong>All Nodes<\/strong><\/p>\n<p>protected-mode no<br \/>\nport 26379<br \/>\ndaemonize no<br \/>\npidfile \/var\/run\/redis-sentinel.pid<br \/>\nloglevel verbose<br \/>\nlogfile \/var\/log\/redis\/sentinel.log<br \/>\ndir \/data\/redis<br \/>\nsentinel monitor mymaster 192.168.1.12 6379 2<br \/>\nsentinel down-after-milliseconds mymaster 3000<br \/>\nsentinel parallel-syncs mymaster 1<br \/>\nsentinel failover-timeout mymaster 5000<br \/>\nsentinel auth-pass mymaster &#8220;Password123&#8221;<br \/>\nsentinel deny-scripts-reconfig yes<\/p>\n<p>chown redis.redis sentinel.conf<\/p>\n<p>chmod 640 sentinel.conf<\/p><\/blockquote>\n<p><strong>3. Create users.acl<\/strong><\/p>\n<blockquote><p>users.acl will provide password authentication for login.<\/p>\n<p>touch \/etc\/redis\/users.acl<\/p>\n<p>chown redis.redis \/etc\/redis\/users.acl<\/p>\n<p>chmod 640 \/etc\/redis\/users.acl<\/p><\/blockquote>\n<h3>Fourth Step : Start Redis and Sentinel Service<\/h3>\n<p><strong>1. Start and Enable Redis Service on All Nodes<\/strong><\/p>\n<blockquote><p>systemctl start redis.service<\/p>\n<p>systemctl enable redis.service<\/p><\/blockquote>\n<p><strong>2. Start and Enable Sentinel Service on All Nodes<\/strong><\/p>\n<blockquote><p>I will create a redis-sentinel.service file because there is not redis-sentinel.service file on my servers.<\/p>\n<p>vi \/etc\/systemd\/system\/redis-sentinel.service<\/p>\n<p>[Unit]<br \/>\nDescription=Redis Sentinel<br \/>\nAfter=network.target<\/p>\n<p>[Service]<br \/>\nExecStart=\/usr\/bin\/redis-sentinel \/etc\/redis\/sentinel.conf &#8211;supervised systemd<br \/>\nExecStop=\/bin\/kill -s TERM $MAINPID<br \/>\nUser=redis<br \/>\nGroup=redis<br \/>\nRestart=always<\/p>\n<p>[Install]<br \/>\nWantedBy=multi-user.target<\/p>\n<p>&nbsp;<\/p>\n<p>systemctl daemon-reexec<\/p>\n<p>systemctl daemon-reload<\/p>\n<p>systemctl start redis-sentinel.service<\/p>\n<p>systemctl enable redis-sentinel.service<\/p><\/blockquote>\n<h3>Fifth Step : Create Users<\/h3>\n<p><strong>1. Create Users on All Nodes<\/strong><\/p>\n<blockquote><p>[root@rds1 redis]# redis-cli<br \/>\n127.0.0.1:6379&gt; auth default Password123<br \/>\nOK<br \/>\n127.0.0.1:6379&gt; ACL SETUSER default on &gt;Password123 allcommands allkeys allchannels<br \/>\nOK<br \/>\n127.0.0.1:6379&gt; ACL SETUSER user1 on &gt;Password123 allcommands allkeys allchannels<br \/>\nOK<br \/>\n127.0.0.1:6379&gt; ACL SAVE<br \/>\nOK<br \/>\n127.0.0.1:6379&gt; ACL LIST<br \/>\n1) &#8220;user default on sanitize-payload #008c70392e3abfbd0fa47bbc2ed96aa99bd49e159727fcba0f2e6abeb3a9d601 ~* &amp;* +@all&#8221;<br \/>\n2) &#8220;user user1 on sanitize-payload #008c70392e3abfbd0fa47bbc2ed96aa99bd49e159727fcba0f2e6abeb3a9d601 ~* &amp;* +@all&#8221;<\/p>\n<p>Also, you can see users at \/etc\/redis\/users.acl file.<\/p><\/blockquote>\n<h3>Sixth Step : Cluster Status Check<\/h3>\n<p><strong>1. Check sentinel.conf<\/strong><\/p>\n<blockquote><p><strong>Master Node<\/strong><\/p>\n<p>more \/etc\/redis\/sentinel.conf<\/p>\n<p>protected-mode no<br \/>\nport 26379<br \/>\ndaemonize no<br \/>\npidfile &#8220;\/var\/run\/redis-sentinel.pid&#8221;<br \/>\nloglevel verbose<br \/>\nlogfile &#8220;\/var\/log\/redis\/sentinel.log&#8221;<br \/>\ndir &#8220;\/data\/redis&#8221;<br \/>\nsentinel monitor mymaster 192.168.1.12 6379 2<br \/>\nsentinel down-after-milliseconds mymaster 3000<\/p>\n<p>sentinel failover-timeout mymaster 5000<br \/>\nsentinel auth-pass mymaster Password123<br \/>\nsentinel deny-scripts-reconfig yes<\/p>\n<p># Generated by CONFIG REWRITE<br \/>\nlatency-tracking-info-percentiles 50 99 99.9<br \/>\nsupervised systemd<br \/>\nuser default on nopass sanitize-payload ~* &amp;* +@all<br \/>\nsentinel myid f03686f91106b6173c30cdcc517527df5fa38943<br \/>\nsentinel config-epoch mymaster 0<br \/>\nsentinel leader-epoch mymaster 0<br \/>\nsentinel current-epoch 0<\/p>\n<p>sentinel known-sentinel mymaster 192.168.1.13 26379 ab94b82a7bc368de19aafb63513ccb2380d243b4<\/p>\n<p>sentinel known-sentinel mymaster 192.168.1.14 26379 23a2bfdc79fa7d96a3e830e89ef3b24290b2fefa<\/p>\n<p>sentinel known-replica mymaster 192.168.1.13 6379<\/p>\n<p>sentinel known-replica mymaster 192.168.1.14 6379<\/p>\n<p><strong>Replica Node 1<\/strong><\/p>\n<p>protected-mode no<br \/>\nport 26379<br \/>\ndaemonize no<br \/>\npidfile &#8220;\/var\/run\/redis-sentinel.pid&#8221;<br \/>\nloglevel verbose<br \/>\nlogfile &#8220;\/var\/log\/redis\/sentinel.log&#8221;<br \/>\ndir &#8220;\/data\/redis&#8221;<br \/>\nsentinel monitor mymaster 192.168.1.12 6379 2<br \/>\nsentinel down-after-milliseconds mymaster 3000<\/p>\n<p>sentinel failover-timeout mymaster 5000<br \/>\nsentinel auth-pass mymaster Password123<br \/>\nsentinel deny-scripts-reconfig yes<\/p>\n<p># Generated by CONFIG REWRITE<br \/>\nsupervised systemd<br \/>\nlatency-tracking-info-percentiles 50 99 99.9<br \/>\nuser default on nopass sanitize-payload ~* &amp;* +@all<br \/>\nsentinel myid ab94b82a7bc368de19aafb63513ccb2380d243b4<br \/>\nsentinel config-epoch mymaster 0<br \/>\nsentinel leader-epoch mymaster 0<br \/>\nsentinel current-epoch 0<\/p>\n<p>sentinel known-replica mymaster 192.168.1.14 6379<\/p>\n<p>sentinel known-sentinel mymaster 192.168.1.12 26379 f03686f91106b6173c30cdcc517527df5fa38943<\/p>\n<p>sentinel known-sentinel mymaster 192.168.1.14 26379 23a2bfdc79fa7d96a3e830e89ef3b24290b2fefa<\/p>\n<p>sentinel known-replica mymaster 192.168.1.13 6379<\/p>\n<p><strong>Replica Node 2<\/strong><\/p>\n<p>protected-mode no<br \/>\nport 26379<br \/>\ndaemonize no<br \/>\npidfile &#8220;\/var\/run\/redis-sentinel.pid&#8221;<br \/>\nloglevel verbose<br \/>\nlogfile &#8220;\/var\/log\/redis\/sentinel.log&#8221;<br \/>\ndir &#8220;\/data\/redis&#8221;<br \/>\nsentinel monitor mymaster 192.168.1.12 6379 2<br \/>\nsentinel down-after-milliseconds mymaster 3000<\/p>\n<p>sentinel failover-timeout mymaster 5000<br \/>\nsentinel auth-pass mymaster Password123<br \/>\nsentinel deny-scripts-reconfig yes<\/p>\n<p># Generated by CONFIG REWRITE<br \/>\nsupervised systemd<br \/>\nlatency-tracking-info-percentiles 50 99 99.9<br \/>\nuser default on nopass sanitize-payload ~* &amp;* +@all<br \/>\nsentinel myid 23a2bfdc79fa7d96a3e830e89ef3b24290b2fefa<br \/>\nsentinel config-epoch mymaster 0<br \/>\nsentinel leader-epoch mymaster 0<br \/>\nsentinel current-epoch 0<\/p>\n<p>sentinel known-sentinel mymaster 192.168.1.13 26379 ab94b82a7bc368de19aafb63513ccb2380d243b4<\/p>\n<p>sentinel known-replica mymaster 192.168.1.14 6379<\/p>\n<p>sentinel known-sentinel mymaster 192.168.1.12 26379 f03686f91106b6173c30cdcc517527df5fa38943<\/p>\n<p>sentinel known-replica mymaster 192.168.1.13 6379<\/p><\/blockquote>\n<p><strong>2. Check Replication<\/strong><\/p>\n<blockquote><p><strong>Master Node<\/strong><\/p>\n<p>[root@rds1 redis]# redis-cli<br \/>\n127.0.0.1:6379&gt; auth default Password123<br \/>\nOK<br \/>\n127.0.0.1:6379&gt; info replication<br \/>\n# Replication<br \/>\nrole:master<br \/>\nconnected_slaves:2<br \/>\nslave0:ip=192.168.1.14,port=6379,state=online,offset=325224,lag=1<br \/>\nslave1:ip=192.168.1.13,port=6379,state=online,offset=325224,lag=1<br \/>\nmaster_failover_state:no-failover<br \/>\nmaster_replid:a0185047c72a48c65d3ff584865dc3675b1d03af<br \/>\nmaster_replid2:0000000000000000000000000000000000000000<br \/>\nmaster_repl_offset:325502<br \/>\nsecond_repl_offset:-1<br \/>\nrepl_backlog_active:1<br \/>\nrepl_backlog_size:1048576<br \/>\nrepl_backlog_first_byte_offset:1<br \/>\nrepl_backlog_histlen:325502<\/p>\n<p><strong>Replica Node 1<\/strong><\/p>\n<p>[root@rds2 redis]# redis-cli<br \/>\n127.0.0.1:6379&gt; auth default Password123<br \/>\nOK<br \/>\n127.0.0.1:6379&gt; info replication<br \/>\n# Replication<br \/>\nrole:slave<br \/>\nmaster_host:192.168.1.12<br \/>\nmaster_port:6379<br \/>\nmaster_link_status:up<br \/>\nmaster_last_io_seconds_ago:1<br \/>\nmaster_sync_in_progress:0<br \/>\nslave_read_repl_offset:361185<br \/>\nslave_repl_offset:361185<br \/>\nslave_priority:2<br \/>\nslave_read_only:1<br \/>\nreplica_announced:1<br \/>\nconnected_slaves:0<br \/>\nmaster_failover_state:no-failover<br \/>\nmaster_replid:a0185047c72a48c65d3ff584865dc3675b1d03af<br \/>\nmaster_replid2:0000000000000000000000000000000000000000<br \/>\nmaster_repl_offset:361185<br \/>\nsecond_repl_offset:-1<br \/>\nrepl_backlog_active:1<br \/>\nrepl_backlog_size:1048576<br \/>\nrepl_backlog_first_byte_offset:9337<br \/>\nrepl_backlog_histlen:351849<\/p>\n<p><strong>Replica Node 2<\/strong><\/p>\n<p>[root@rds3 redis]# redis-cli<br \/>\n127.0.0.1:6379&gt; auth default Password123<br \/>\nOK<br \/>\n127.0.0.1:6379&gt; info replication<br \/>\n# Replication<br \/>\nrole:slave<br \/>\nmaster_host:192.168.1.12<br \/>\nmaster_port:6379<br \/>\nmaster_link_status:up<br \/>\nmaster_last_io_seconds_ago:1<br \/>\nmaster_sync_in_progress:0<br \/>\nslave_read_repl_offset:371263<br \/>\nslave_repl_offset:371263<br \/>\nslave_priority:3<br \/>\nslave_read_only:1<br \/>\nreplica_announced:1<br \/>\nconnected_slaves:0<br \/>\nmaster_failover_state:no-failover<br \/>\nmaster_replid:a0185047c72a48c65d3ff584865dc3675b1d03af<br \/>\nmaster_replid2:0000000000000000000000000000000000000000<br \/>\nmaster_repl_offset:371263<br \/>\nsecond_repl_offset:-1<br \/>\nrepl_backlog_active:1<br \/>\nrepl_backlog_size:1048576<br \/>\nrepl_backlog_first_byte_offset:9337<br \/>\nrepl_backlog_histlen:361927<\/p><\/blockquote>\n<p><strong>3. Check Sentinel<\/strong><\/p>\n<blockquote><p>[root@rds1 redis]# redis-cli -p 26379<br \/>\n127.0.0.1:26379&gt; auth default Password123<br \/>\nOK<br \/>\n127.0.0.1:26379&gt; sentinel masters<br \/>\n1) 1) &#8220;name&#8221;<br \/>\n2) &#8220;mymaster&#8221;<br \/>\n3) &#8220;ip&#8221;<br \/>\n4) &#8220;192.168.1.12&#8221;<br \/>\n5) &#8220;port&#8221;<br \/>\n6) &#8220;6379&#8221;<br \/>\n7) &#8220;runid&#8221;<br \/>\n8) &#8220;fd52c7129201e03249df7b579b5ac75b8d1b5886&#8221;<br \/>\n9) &#8220;flags&#8221;<br \/>\n10) &#8220;master&#8221;<br \/>\n11) &#8220;link-pending-commands&#8221;<br \/>\n12) &#8220;0&#8221;<br \/>\n13) &#8220;link-refcount&#8221;<br \/>\n14) &#8220;1&#8221;<br \/>\n15) &#8220;last-ping-sent&#8221;<br \/>\n16) &#8220;0&#8221;<br \/>\n17) &#8220;last-ok-ping-reply&#8221;<br \/>\n18) &#8220;118&#8221;<br \/>\n19) &#8220;last-ping-reply&#8221;<br \/>\n20) &#8220;118&#8221;<br \/>\n21) &#8220;down-after-milliseconds&#8221;<br \/>\n22) &#8220;3000&#8221;<br \/>\n23) &#8220;info-refresh&#8221;<br \/>\n24) &#8220;6876&#8221;<br \/>\n25) &#8220;role-reported&#8221;<br \/>\n26) &#8220;master&#8221;<br \/>\n27) &#8220;role-reported-time&#8221;<br \/>\n28) &#8220;2326059&#8221;<br \/>\n29) &#8220;config-epoch&#8221;<br \/>\n30) &#8220;0&#8221;<br \/>\n31) &#8220;num-slaves&#8221;<br \/>\n32) &#8220;2&#8221;<br \/>\n33) &#8220;num-other-sentinels&#8221;<br \/>\n34) &#8220;2&#8221;<br \/>\n35) &#8220;quorum&#8221;<br \/>\n36) &#8220;2&#8221;<br \/>\n37) &#8220;failover-timeout&#8221;<br \/>\n38) &#8220;5000&#8221;<br \/>\n39) &#8220;parallel-syncs&#8221;<br \/>\n40) &#8220;1&#8221;<\/p>\n<p>127.0.0.1:26379&gt; SENTINEL get-master-addr-by-name mymaster<br \/>\n1) &#8220;192.168.1.12&#8221;<br \/>\n2) &#8220;6379&#8221;<\/p>\n<p>127.0.0.1:26379&gt; SENTINEL slaves mymaster<br \/>\n1) 1) &#8220;name&#8221;<br \/>\n2) &#8220;192.168.1.14:6379&#8221;<br \/>\n3) &#8220;ip&#8221;<br \/>\n4) &#8220;192.168.1.14&#8221;<br \/>\n5) &#8220;port&#8221;<br \/>\n6) &#8220;6379&#8221;<br \/>\n7) &#8220;runid&#8221;<br \/>\n8) &#8220;19083afb2af517c11dd12d52366f52b605f11898&#8221;<br \/>\n9) &#8220;flags&#8221;<br \/>\n10) &#8220;slave&#8221;<br \/>\n11) &#8220;link-pending-commands&#8221;<br \/>\n12) &#8220;0&#8221;<br \/>\n13) &#8220;link-refcount&#8221;<br \/>\n14) &#8220;1&#8221;<br \/>\n15) &#8220;last-ping-sent&#8221;<br \/>\n16) &#8220;0&#8221;<br \/>\n17) &#8220;last-ok-ping-reply&#8221;<br \/>\n18) &#8220;130&#8221;<br \/>\n19) &#8220;last-ping-reply&#8221;<br \/>\n20) &#8220;130&#8221;<br \/>\n21) &#8220;down-after-milliseconds&#8221;<br \/>\n22) &#8220;3000&#8221;<br \/>\n23) &#8220;info-refresh&#8221;<br \/>\n24) &#8220;5673&#8221;<br \/>\n25) &#8220;role-reported&#8221;<br \/>\n26) &#8220;slave&#8221;<br \/>\n27) &#8220;role-reported-time&#8221;<br \/>\n28) &#8220;2465451&#8221;<br \/>\n29) &#8220;master-link-down-time&#8221;<br \/>\n30) &#8220;0&#8221;<br \/>\n31) &#8220;master-link-status&#8221;<br \/>\n32) &#8220;ok&#8221;<br \/>\n33) &#8220;master-host&#8221;<br \/>\n34) &#8220;192.168.1.12&#8221;<br \/>\n35) &#8220;master-port&#8221;<br \/>\n36) &#8220;6379&#8221;<br \/>\n37) &#8220;slave-priority&#8221;<br \/>\n38) &#8220;3&#8221;<br \/>\n39) &#8220;slave-repl-offset&#8221;<br \/>\n40) &#8220;526637&#8221;<br \/>\n41) &#8220;replica-announced&#8221;<br \/>\n42) &#8220;1&#8221;<br \/>\n2) 1) &#8220;name&#8221;<br \/>\n2) &#8220;192.168.1.13:6379&#8221;<br \/>\n3) &#8220;ip&#8221;<br \/>\n4) &#8220;192.168.1.13&#8221;<br \/>\n5) &#8220;port&#8221;<br \/>\n6) &#8220;6379&#8221;<br \/>\n7) &#8220;runid&#8221;<br \/>\n8) &#8220;a3304c327c08fc35b58b45820fde6c86dc3eb396&#8221;<br \/>\n9) &#8220;flags&#8221;<br \/>\n10) &#8220;slave&#8221;<br \/>\n11) &#8220;link-pending-commands&#8221;<br \/>\n12) &#8220;0&#8221;<br \/>\n13) &#8220;link-refcount&#8221;<br \/>\n14) &#8220;1&#8221;<br \/>\n15) &#8220;last-ping-sent&#8221;<br \/>\n16) &#8220;0&#8221;<br \/>\n17) &#8220;last-ok-ping-reply&#8221;<br \/>\n18) &#8220;130&#8221;<br \/>\n19) &#8220;last-ping-reply&#8221;<br \/>\n20) &#8220;130&#8221;<br \/>\n21) &#8220;down-after-milliseconds&#8221;<br \/>\n22) &#8220;3000&#8221;<br \/>\n23) &#8220;info-refresh&#8221;<br \/>\n24) &#8220;5673&#8221;<br \/>\n25) &#8220;role-reported&#8221;<br \/>\n26) &#8220;slave&#8221;<br \/>\n27) &#8220;role-reported-time&#8221;<br \/>\n28) &#8220;2465451&#8221;<br \/>\n29) &#8220;master-link-down-time&#8221;<br \/>\n30) &#8220;0&#8221;<br \/>\n31) &#8220;master-link-status&#8221;<br \/>\n32) &#8220;ok&#8221;<br \/>\n33) &#8220;master-host&#8221;<br \/>\n34) &#8220;192.168.1.12&#8221;<br \/>\n35) &#8220;master-port&#8221;<br \/>\n36) &#8220;6379&#8221;<br \/>\n37) &#8220;slave-priority&#8221;<br \/>\n38) &#8220;2&#8221;<br \/>\n39) &#8220;slave-repl-offset&#8221;<br \/>\n40) &#8220;526637&#8221;<br \/>\n41) &#8220;replica-announced&#8221;<br \/>\n42) &#8220;1&#8221;<\/p><\/blockquote>\n<p><strong>4. Check Log Files<\/strong><\/p>\n<blockquote><p>tail -100f \/var\/log\/redis\/redis.log<\/p>\n<p>tail -100f \/var\/log\/redis\/sentinel.log<\/p>\n<p>tail -100f \/var\/log\/messages<\/p><\/blockquote>\n<p><strong>5. Check Latency<\/strong><\/p>\n<blockquote><p>[root@rds1 redis]# redis-cli &#8211;latency<br \/>\nmin: 0, max: 1, avg: 0.02 (176 samples)<\/p><\/blockquote>\n<h3>Seventh Step : Keepalived Virtual IP Configuration<\/h3>\n<p>We will use a virtual IP which is 192.168.1.11 for connecting to redis from applications. So, I configure keepalived service on all nodes regarding to redis.<\/p>\n<p><strong>1.Keepalived Package Install<\/strong><\/p>\n<blockquote><p>dnf install keepalived<\/p><\/blockquote>\n<p><strong>2.Create redis master check bash script<\/strong><\/p>\n<blockquote><p>cd \/etc\/keepalived<\/p>\n<p>vi check_redis_master.sh<\/p>\n<p>#!\/bin\/bash<\/p>\n<p>ROLE=$(redis-cli -a Password123 INFO replication 2&gt;\/dev\/null | grep -v &#8220;Warning&#8221; | grep role | cut -d&#8217;:&#8217; -f2 | tr -d &#8216;\\r&#8217;)<\/p>\n<p>if [ &#8220;$ROLE&#8221; == &#8220;master&#8221; ]; then<br \/>\nexit 0<br \/>\nelse<br \/>\nexit 1<br \/>\nfi<\/p>\n<p>chmod +x check_redis_master.sh<\/p><\/blockquote>\n<p><strong>3.Configure keepalived.conf<\/strong><\/p>\n<blockquote><p>vi keepalived.conf<\/p>\n<p>vrrp_script chk_redis {<br \/>\nscript &#8220;\/etc\/keepalived\/check_redis_master.sh&#8221;<br \/>\ninterval 2<br \/>\nweight 10<br \/>\n}<\/p>\n<p>vrrp_instance VI_1 {<br \/>\nstate MASTER<br \/>\ninterface ens160<br \/>\nvirtual_router_id 51<br \/>\npriority 100<br \/>\nadvert_int 1<br \/>\nauthentication {<br \/>\nauth_type PASS<br \/>\nauth_pass Pass1234<br \/>\n}<br \/>\nvirtual_ipaddress {<br \/>\n192.168.1.11<br \/>\n}<br \/>\ntrack_script {<br \/>\nchk_redis<br \/>\n}<br \/>\n}<\/p>\n<p>First node keepalived.conf will be like above. Second node keepalived.conf some parameters will change like that state BACKUP and priority 90. Third node keepalived.conf some parameters will change like that state BACKUP and priority 80.<\/p><\/blockquote>\n<p><strong>4. Start Keepalived Service<\/strong><\/p>\n<blockquote><p>systemctl start keepalived.service<\/p>\n<p>systemctl enable keepalived.service<\/p><\/blockquote>\n<p><strong>5. Check IP<\/strong><\/p>\n<blockquote><p>You can check IP with ip a command<\/p><\/blockquote>\n<h3>Eighth Step : Failover Operations<\/h3>\n<p>Redis Sentinel manages failover operations and chooses new master from candidates. Redis Sentinel make failover automatically when reboot or interruption on master node. Also you can make failover manually with below commands.<\/p>\n<p><strong>1.Check Status Before Failover<\/strong><\/p>\n<blockquote><p>[root@rds1 redis]# redis-cli<br \/>\n127.0.0.1:6379&gt; auth default Password123<br \/>\nOK<br \/>\n127.0.0.1:6379&gt; info replication<br \/>\n# Replication<br \/>\nrole:master<br \/>\nconnected_slaves:2<br \/>\nslave0:ip=192.168.1.14,port=6379,state=online,offset=754198,lag=0<br \/>\nslave1:ip=192.168.1.13,port=6379,state=online,offset=754198,lag=0<br \/>\nmaster_failover_state:no-failover<br \/>\nmaster_replid:03026581141f83e6224b3ad1a15b982b8b5854dc<br \/>\nmaster_replid2:e6be901b80683835a598cee49dfed0b412d62ed7<br \/>\nmaster_repl_offset:754198<br \/>\nsecond_repl_offset:739868<br \/>\nrepl_backlog_active:1<br \/>\nrepl_backlog_size:1048576<br \/>\nrepl_backlog_first_byte_offset:653194<br \/>\nrepl_backlog_histlen:101005<\/p>\n<p>connected_slaves count has to be suitable.<br \/>\nlag has to be 0 or max 1.<br \/>\noffset has to be the same or near.<br \/>\nstate has to be online.<\/p><\/blockquote>\n<p><strong>2.Failover<\/strong><\/p>\n<blockquote><p>[root@rds1 redis]# redis-cli -p 26379 SENTINEL failover mymaster<br \/>\nOK<br \/>\n[root@rds1 redis]# redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster<br \/>\n1) &#8220;192.168.1.13&#8221;<br \/>\n2) &#8220;6379&#8221;<\/p>\n<p>As you see second node is new master now.<\/p><\/blockquote>\n<h3>Bonus : Useful Commands<\/h3>\n<p><strong>1.DML<\/strong><\/p>\n<blockquote><p><strong>SET key value<\/strong> Sets a key to hold the specified value<br \/>\n<strong>GET key<\/strong> Gets the value of a key<br \/>\n<strong>DEL key<\/strong> Deletes a key<br \/>\n<strong>EXISTS key<\/strong> Checks if a key exists (returns 1 or 0)<br \/>\n<strong>EXPIRE key seconds<\/strong> Sets a time-to-live (TTL) for a key<br \/>\n<strong>TTL key<\/strong> Gets remaining TTL for a key<br \/>\n<strong>INCR key<\/strong> Increments the integer value of a key by one<br \/>\n<strong>DECR key<\/strong> Decrements the integer value of a key by one<br \/>\n<strong>APPEND key value<\/strong> Appends value to an existing key<\/p><\/blockquote>\n<p><strong>2.List<\/strong><\/p>\n<blockquote><p><strong>LPUSH key value<\/strong> Inserts value at the head of the list<br \/>\n<strong>RPUSH key value<\/strong> Inserts value at the end of the list<br \/>\n<strong>LPOP key<\/strong> Removes and returns the first element<br \/>\n<strong>RPOP key<\/strong> Removes and returns the last element<br \/>\n<strong>LRANGE key 0 -1<\/strong> Returns elements between given indexes<\/p><\/blockquote>\n<p><strong>3.Set<\/strong><\/p>\n<blockquote><p><strong>SADD key value<\/strong> Adds a value to a set<br \/>\n<strong>SREM key value<\/strong> Removes a value from a set<br \/>\n<strong>SMEMBERS key<\/strong> Gets all members of the set<br \/>\n<strong>SISMEMBER key value<\/strong> Checks if a value exists in the set<\/p><\/blockquote>\n<p><strong>4.Hash<\/strong><\/p>\n<blockquote><p><strong>HSET key field value<\/strong> Sets a field in a hash<br \/>\n<strong>HGET key field<\/strong> Gets the value of a field in a hash<br \/>\n<strong>HDEL key field<\/strong> Deletes a field from a hash<br \/>\n<strong>HGETALL key<\/strong> Gets all fields and values in a hash<\/p><\/blockquote>\n<p><strong>5.DDL<\/strong><\/p>\n<blockquote><p><strong>KEYS *<\/strong> Lists all keys (not recommended for production)<br \/>\n<strong>FLUSHDB<\/strong> Deletes all keys in the current DB<br \/>\n<strong>FLUSHALL<\/strong> Deletes all keys in all databases<br \/>\n<strong>RENAME old new<\/strong> Renames a key<br \/>\n<strong>TYPE key<\/strong> Returns the data type of the key<\/p><\/blockquote>\n<p><strong>6.Config<\/strong><\/p>\n<blockquote><p><strong>SAVE<\/strong> Performs a synchronous save to disk<br \/>\n<strong>BGSAVE<\/strong> Performs an asynchronous background save<br \/>\n<strong>LASTSAVE<\/strong> Shows the last successful save time<br \/>\n<strong>CONFIG GET &lt;pattern&gt;<\/strong> Gets configuration parameters<br \/>\n<strong>CONFIG SET &lt;param&gt; &lt;value&gt;<\/strong> Dynamically sets a configuration value<\/p><\/blockquote>\n<p><strong>7.Control &amp; Monitor<\/strong><\/p>\n<blockquote><p><strong>INFO replication<\/strong> Shows replication role and status<br \/>\n<strong>INFO persistence<\/strong> Shows persistence status<br \/>\n<strong>SLAVEOF host port<\/strong> Makes the server a replica of another instance<br \/>\n<strong>SENTINEL get-master-addr-by-name name<\/strong> Returns IP\/Port of monitored master<br \/>\n<strong>MONITOR<\/strong> Streams all received commands in real-time<br \/>\n<strong>SLOWLOG get<\/strong> Shows list of slow commands<br \/>\n<strong>INFO<\/strong> Displays detailed information about Redis server<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Redis is an open-source, in-memory data structure store, widely used as a database, cache, and message broker. Known for its lightning-fast performance, Redis operates by keeping data in memory rather than on disk, which allows for incredibly quick read and write operations. It supports a variety of data structures such as strings, hashes, lists, sets,&#8230;<\/p>\n","protected":false},"author":37,"featured_media":3012,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[129],"tags":[131,132,130],"class_list":["post-2995","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-redis","tag-database","tag-nosql","tag-redis"],"jetpack_featured_media_url":"http:\/\/www.fatihacar.com\/blog\/resimler\/redis_sentinel.png","jetpack_shortlink":"https:\/\/wp.me\/p39NFI-Mj","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/posts\/2995","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/comments?post=2995"}],"version-history":[{"count":22,"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/posts\/2995\/revisions"}],"predecessor-version":[{"id":3014,"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/posts\/2995\/revisions\/3014"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/media\/3012"}],"wp:attachment":[{"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/media?parent=2995"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/categories?post=2995"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fatihacar.com\/blog\/wp-json\/wp\/v2\/tags?post=2995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}