{"id":7535,"date":"2018-06-03T10:55:45","date_gmt":"2018-06-03T02:55:45","guid":{"rendered":"http:\/\/rmohan.com\/?p=7535"},"modified":"2018-06-03T10:55:45","modified_gmt":"2018-06-03T02:55:45","slug":"redis-master-slave-keepalived-achieve-high-availability","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=7535","title":{"rendered":"Redis master-slave + KeepAlived achieve high availability"},"content":{"rendered":"<p><strong>Redis master-slave + KeepAlived achieve high availability<\/strong><\/p>\n<p>Redis is a non-relational database that we currently use more frequently. It can support diverse data types, multi-threaded high concurrency support, and redis running in memory with faster read and write. Because of the excellent performance of redis, how can we ensure that redis can deal with downtime during operation?<\/p>\n<p>So today&#8217;s summary of the construction of the redis master-slave high-availability system, with reference to online bloggers of some great gods, found that many are pitted, so I share this one time, hoping to help everyone.<\/p>\n<p>Redis Features<br \/>\nRedis is completely open source free, complies with the BSD protocol and is a high performance key-value database.<\/p>\n<p>Redis and other key-value cache products have the following three characteristics:<\/p>\n<p>Redis supports the persistence of data, can keep the data in memory on the disk, and can be loaded again for use when restarted.<\/p>\n<p>Redis not only supports simple key-value types of data, but also provides data structures such as: Strings, Maps, Lists, Sets, and sorted sets. Storage.<\/p>\n<p>Redis supports data backup, that is, data backup in master-slave mode.<\/p>\n<p>The Redis advantage<br \/>\nis extremely high \u2013 Redis can read 100K+ times\/s and write at 80K+ times\/s.<\/p>\n<p>Rich data types \u2013 Redis supports Strings, Lists, Hashes, Sets, and Ordered Sets data type operations for binary cases.<\/p>\n<p>Atoms &#8211; All operations of Redis are atomic, and Redis also supports atomic execution of all operations after all operations.<\/p>\n<p>Rich features &#8211; Redis also supports publish\/subscribe, notifications, key expiration, and more.<\/p>\n<p>Prepare environment<\/p>\n<p>CentOS 7 &#8211;&gt; 172.16.81.140 &#8211;&gt; Master Redis &#8211;&gt; Master Keepalived<\/p>\n<p>CentOS7 &#8211;&gt; 172.16.81.141 &#8211;&gt; From Redis &#8211;&gt; Prepared Keepalived<\/p>\n<p>VIP &#8211;&gt; 172.16.81.139<\/p>\n<p>Redis (normally 3.0 or later)<\/p>\n<p>KeepAlived (direct online installation)<\/p>\n<p>Redis compile and install<\/p>\n<p>cd \/opt<br \/>\ntar -zxvf redis-4.0.6.tar.gz<br \/>\nmv redis-4.0.6 redis<br \/>\ncd redis<br \/>\nmakeMALLOC=libc<br \/>\nmake PREFIX=\/usr\/local\/redis install<\/p>\n<p>2, configure the redis startup script<\/p>\n<p>vim \/etc\/init.d\/redis<\/p>\n<p>#!\/bin\/sh<\/p>\n<p>#chkconfig:2345 80 90<br \/>\n# Simple Redisinit.d script conceived to work on Linux systems<br \/>\n# as it doeSUSE of the \/proc filesystem.<\/p>\n<p># Configure the redis port number<br \/>\nREDISPORT=6379<br \/>\n# Configure the redis startup command path<br \/>\nEXE=\/usr\/local\/redis\/bin\/ redisserver<br \/>\n# Configure the redis connection command path<br \/>\nCLIEXE=\/usr\/local\/redis\/bin\/redis-cli<br \/>\n# Configure<br \/>\nRedis Run PID path PIDFILE=\/var\/run\/redis_6379.pid<br \/>\n# Configure the path of redis configuration file<br \/>\nCONF=&#8221;\/etc\/redis\/redis.conf&#8221;<br \/>\n# Configure the connection authentication password for redis<br \/>\nREDISPASSWORD=123456<br \/>\nfunction start () {<br \/>\nif [ -f $PIDFILE ]<\/p>\n<p>then<\/p>\n<p>echo &#8220;$PIDFILE exists,process is already running or crashed&#8221;<\/p>\n<p>else<\/p>\n<p>echo &#8220;Starting Redisserver&#8230;&#8221;<\/p>\n<p>$EXE $CONF &amp;<\/p>\n<p>fi<br \/>\n}<\/p>\n<p>function stop () {<br \/>\nif [ ! -f $PIDFILE ]<\/p>\n<p>then<\/p>\n<p>echo &#8220;$PIDFILE does not exist, process is not running&#8221;<\/p>\n<p>else<\/p>\n<p>PID=$(cat $PIDFILE)<\/p>\n<p>echo &#8220;Stopping &#8230;&#8221;<\/p>\n<p>$CLIEXE -p $REDISPORT -a $REDISPASSWORD shutdown<\/p>\n<p>while [ -x \/proc\/${PID} ]<\/p>\n<p>do<\/p>\n<p>echo &#8220;Waiting forRedis to shutdown &#8230;&#8221;<\/p>\n<p>sleep 1<\/p>\n<p>done<\/p>\n<p>echo &#8220;Redis stopped&#8221;<\/p>\n<p>fi<br \/>\n}<\/p>\n<p>function restart () {<br \/>\nstop<\/p>\n<p>sleep 3<\/p>\n<p>start<br \/>\n}<\/p>\n<p>case &#8220;$1&#8221; in<br \/>\nstart)<br \/>\nstart<br \/>\n;;<br \/>\nstop)<br \/>\nstop<br \/>\n;;<br \/>\nrestart)<br \/>\nrestart<br \/>\n;;<br \/>\n*)<br \/>\necho -e &#8220;\\e[31m Please use $0 [start|stop|restart] asfirst argument \\e[0m&#8221;<br \/>\n;;<br \/>\nesac<\/p>\n<p>Grant execution permissions:<\/p>\n<p>chmod +x \/etc\/init.d\/redis<\/p>\n<p>Add boot start:<\/p>\n<p>chkconfig &#8211;add redis<\/p>\n<p>chkconfig redis on<\/p>\n<p>See: chkconfig &#8211;list | grep redis<\/p>\n<p>The test closed the firewall and selinux beforehand. The production environment is recommended to open the firewall.<\/p>\n<p>3, add redis command environment variables<\/p>\n<p>#vi \/etc\/profile #Add the<br \/>\nnext line of parameters<br \/>\nexportPATH=&#8221;$PATH:\/usr\/local\/redis\/bin&#8221; #Environment<br \/>\nvariables become effective<br \/>\nsource \/etc\/profile<\/p>\n<p>4. Start redis service<\/p>\n<p>Service redis start #Check<br \/>\nstartup<\/p>\n<p>ps -ef | grep redis<\/p>\n<p>Note: After we perform the same operation on our two servers, the installation completes redis. After the installation is completed, we directly enter the configuration master-slave environment.<\/p>\n<p>Redis master-slave configuration<\/p>\n<p>To extend back to the previous design pattern, our idea is to use 140 as the master, 141 as the slave, and 139 as the VIP elegant address. The application accesses the redis database through the 6379 port of the 139.<\/p>\n<p>In normal operation, when the master node 140 goes down, the VIP floats to 141, and then 141 will take over 140 as the master node, and 140 will become the slave node, continuing to provide read and write operations.<\/p>\n<p>When 140 returns to normal, 140 will perform data synchronization with 141 at this time, 140 the original data will not be lost, and the data that has been written into 141 between synchronization machines will be synchronized. After the data synchronization is completed,<\/p>\n<p>The VIP will return to the 140 node and become the master node because of the weight. 141 will lose the VIP and become the slave node again, and restore to the initial state to continue providing uninterrupted read and write services.<\/p>\n<p>1, configure the redis configuration file<\/p>\n<p>Master-140 configuration file<\/p>\n<p>vim \/etc\/redis\/redis.conf<br \/>\nbind 0.0.0.0<br \/>\nport 6379<br \/>\ndaemonize yes<br \/>\nrequirepass 123456<br \/>\nslave-serve-stale-data yes<br \/>\nslave-read-only no<\/p>\n<p>Slave-141 configuration file<\/p>\n<p>vim \/etc\/redis\/redis.conf<br \/>\nbind 0.0.0.0<br \/>\nport 6379<br \/>\ndaemonize yes<br \/>\nslaveof 172.16.81.140 6379<br \/>\nmasterauth 123456<br \/>\nslave-serve-stale-data yes<br \/>\nslave-read-only no<\/p>\n<p>2. Restart the redis service after the configuration is complete! Verify that the master and slave are normal.<\/p>\n<p>Master node 140 terminal login test:<\/p>\n<p>[root@localhost ~]# redis-cli -a 123456<br \/>\n127.0.0.1:6379&gt; INFO<br \/>\n.<br \/>\n.<br \/>\n.<br \/>\n# Replication<br \/>\nrole:master<br \/>\nconnected_slaves:1<br \/>\nslave0:ip=172.16.81.141,port=6379,state=online,offset=105768,lag=1<br \/>\nmaster_replid:f83fcc3c98614d770f2205831fef1e877fa3f482<br \/>\nmaster_replid2:1f25604997a4ad3eb8344e8155990e78acd93312<br \/>\nmaster_repl_offset:105768<br \/>\nsecond_repl_offset:447<br \/>\nrepl_backlog_active:1<br \/>\nrepl_backlog_size:1048576<br \/>\nrepl_backlog_first_byte_offset:447<br \/>\nrepl_backlog_histlen:105322<\/p>\n<p>Login test from node 141 terminal:<\/p>\n<p>[root@localhost ~]# redis-cli -a 123456<br \/>\n127.0.0.1:6379&gt; info<br \/>\n.<br \/>\n.<br \/>\n.<br \/>\n# Replication<br \/>\nrole:slave<br \/>\nmaster_host:172.16.81.140<br \/>\nmaster_port:6379<br \/>\nmaster_link_status:up<br \/>\nmaster_last_io_seconds_ago:5<br \/>\nmaster_sync_in_progress:0<br \/>\nslave_repl_offset:105992<br \/>\nslave_priority:100<br \/>\nslave_read_only:0<br \/>\nconnected_slaves:0<br \/>\nmaster_replid:f83fcc3c98614d770f2205831fef1e877fa3f482<br \/>\nmaster_replid2:1f25604997a4ad3eb8344e8155990e78acd93312<br \/>\nmaster_repl_offset:105992<br \/>\nsecond_repl_offset:447<br \/>\nrepl_backlog_active:1<br \/>\nrepl_backlog_size:1048576<br \/>\nrepl_backlog_first_byte_offset:239<br \/>\nrepl_backlog_histlen:105754<br \/>\n3, synchronous test<\/p>\n<p>Master node 140<\/p>\n<p>The masters and slaves of this redis have been completed!<\/p>\n<p>KeepAlived configuration to achieve dual hot standby<\/p>\n<p>Use Keepalived to implement VIP, and achieve disaster recovery through notify_master, notify_backup, notify_fault, notify_stop.<\/p>\n<p>1, configure Keepalived configuration file<\/p>\n<p>Master Keepalived Profile<\/p>\n<p>vim \/etc\/keepalived\/keepalived.conf<br \/>\n! Configuration File for keepalived<\/p>\n<p>global_defs {<br \/>\nnotification_email {<br \/>\nacassen@firewall.loc<br \/>\nfailover@firewall.loc<br \/>\nsysadmin@firewall.loc<br \/>\n}<br \/>\nnotification_email_from Alexandre.Cassen@firewall.loc<br \/>\nsmtp_server 192.168.200.1<br \/>\nsmtp_connect_timeout 30<br \/>\nrouter_id redis01<br \/>\n}<\/p>\n<p>vrrp_script chk_redis {<br \/>\nscript &#8220;\/etc\/keepalived\/script\/redis_check.sh&#8221;<br \/>\ninterval 2<br \/>\n}<\/p>\n<p>vrrp_instance VI_1 {<br \/>\nstate MASTER<br \/>\ninterface eno16777984<br \/>\nvirtual_router_id 51<br \/>\npriority 100<br \/>\nadvert_int 1<br \/>\nauthentication {<br \/>\nauth_type PASS<br \/>\nauth_pass 1111<br \/>\n}<\/p>\n<p>track_script {<br \/>\nchk_redis<br \/>\n}<br \/>\nvirtual_ipaddress {<br \/>\n172.16.81.139<br \/>\n}<\/p>\n<p>notify_master \/etc\/keepalived\/script\/redis_master.sh<br \/>\nnotify_backup \/etc\/keepalived\/script\/redis_backup.sh<br \/>\nnotify_fault \/etc\/keepalived\/script\/redis_fault.sh<br \/>\nnotify_stop \/etc\/keepalived\/script\/redis_stop.sh<br \/>\n}<\/p>\n<p>Spare Keepalived Profile<\/p>\n<p>vim \/etc\/keepalived\/keepalived.conf<br \/>\n! Configuration File for keepalived<\/p>\n<p>global_defs {<br \/>\nnotification_email {<br \/>\nacassen@firewall.loc<br \/>\nfailover@firewall.loc<br \/>\nsysadmin@firewall.loc<br \/>\n}<br \/>\nnotification_email_from Alexandre.Cassen@firewall.loc<br \/>\nsmtp_server 192.168.200.1<br \/>\nsmtp_connect_timeout 30<br \/>\nrouter_id redis02<br \/>\n}<\/p>\n<p>vrrp_script chk_redis {<br \/>\nscript &#8220;\/etc\/keepalived\/script\/redis_check.sh&#8221;<br \/>\ninterval 2<br \/>\n}<\/p>\n<p>vrrp_instance VI_1 {<br \/>\nstate BACKUP<br \/>\ninterface eno16777984<br \/>\nvirtual_router_id 51<br \/>\npriority 99<br \/>\nadvert_int 1<br \/>\nauthentication {<br \/>\nauth_type PASS<br \/>\nauth_pass 1111<br \/>\n}<\/p>\n<p>track_script {<br \/>\nchk_redis<br \/>\n}<br \/>\nvirtual_ipaddress {<br \/>\n172.16.81.139<br \/>\n}<\/p>\n<p>notify_master \/etc\/keepalived\/script\/redis_master.sh<br \/>\nnotify_backup \/etc\/keepalived\/script\/redis_backup.sh<br \/>\nnotify_fault \/etc\/keepalived\/script\/redis_fault.sh<br \/>\nnotify_stop \/etc\/keepalived\/script\/redis_stop.sh<br \/>\n}<\/p>\n<p>2, configure the script<\/p>\n<p>Master KeepAlived &#8212; 140<\/p>\n<p>Create a script directory: mkdir -p \/etc\/keepalived\/script\/<\/p>\n<p>cd \/etc\/keepalived\/script\/<\/p>\n<p>[root@localhost script]# cat redis_check.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>ALIVE=`\/usr\/local\/redis\/bin\/redis-cli -a 123456 PING`<\/p>\n<p>if [ &#8220;$ALIVE&#8221; == &#8220;PONG&#8221; ];then<\/p>\n<p>echo $ALIVE<\/p>\n<p>exit 0<\/p>\n<p>else<\/p>\n<p>echo $ALIVE<\/p>\n<p>exit 1<\/p>\n<p>fi<\/p>\n<p>[root@localhost script]# cat redis_master.sh<br \/>\n#!\/bin\/bash<br \/>\nREDISCLI=&#8221;\/usr\/local\/redis\/bin\/redis-cli -a 123456&#8243;<br \/>\nLOGFILE=&#8221;\/var\/log\/keepalived-redis-state.log&#8221;<br \/>\nsleep 15<br \/>\necho &#8220;[master]&#8221; &gt;&gt; $LOGFILE<br \/>\ndate &gt;&gt; $LOGFILE<br \/>\necho &#8220;Being master&#8230;.&#8221; &gt;&gt;$LOGFILE 2&gt;&amp;1<br \/>\necho &#8220;Run SLAVEOF cmd &#8230;&#8221;&gt;&gt; $LOGFILE<br \/>\n$REDISCLI SLAVEOF 172.16.81.141 6379 &gt;&gt;$LOGFILE 2&gt;&amp;1<br \/>\nif [ $? -ne 0 ];then<br \/>\necho &#8220;data rsync fail.&#8221; &gt;&gt;$LOGFILE 2&gt;&amp;1<br \/>\nelse<br \/>\necho &#8220;data rsync OK.&#8221; &gt;&gt; $LOGFILE 2&gt;&amp;1<br \/>\nfi<\/p>\n<p>Sleep 10 # delay 10 seconds later to cancel synchronization after the data synchronization is complete<\/p>\n<p>echo &#8220;Run SLAVEOF NO ONE cmd &#8230;&#8221;&gt;&gt; $LOGFILE<\/p>\n<p>$REDISCLI SLAVEOF NO ONE &gt;&gt; $LOGFILE 2&gt;&amp;1<br \/>\nif [ $? -ne 0 ];then<br \/>\necho &#8220;Run SLAVEOF NO ONE cmd fail.&#8221; &gt;&gt;$LOGFILE 2&gt;&amp;1<br \/>\nelse<br \/>\necho &#8220;Run SLAVEOF NO ONE cmd OK.&#8221; &gt;&gt; $LOGFILE 2&gt;&amp;1<br \/>\nfi<\/p>\n<p>[root@localhost script]# cat redis_backup.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>REDISCLI=&#8221;\/usr\/local\/redis\/bin\/redis-cli -a 123456&#8243;<\/p>\n<p>LOGFILE=&#8221;\/var\/log\/keepalived-redis-state.log&#8221;<\/p>\n<p>echo &#8220;[backup]&#8221; &gt;&gt; $LOGFILE<\/p>\n<p>date &gt;&gt; $LOGFILE<\/p>\n<p>echo &#8220;Being slave&#8230;.&#8221; &gt;&gt;$LOGFILE 2&gt;&amp;1<\/p>\n<p>Sleep 15 #delay 15 seconds to wait until the data is synchronized to the other side and then switch the role of master-slave<\/p>\n<p>echo &#8220;Run SLAVEOF cmd &#8230;&#8221;&gt;&gt; $LOGFILE<\/p>\n<p>$REDISCLI SLAVEOF 172.16.81.141 6379 &gt;&gt;$LOGFILE 2&gt;&amp;1<\/p>\n<p>[root@localhost script]# cat redis_fault.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>LOGFILE=\/var\/log\/keepalived-redis-state.log<\/p>\n<p>echo &#8220;[fault]&#8221; &gt;&gt; $LOGFILE<\/p>\n<p>date &gt;&gt; $LOGFILE<\/p>\n<p>[root@localhost script]# cat redis_stop.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>LOGFILE=\/var\/log\/keepalived-redis-state.log<\/p>\n<p>echo &#8220;[stop]&#8221; &gt;&gt; $LOGFILE<\/p>\n<p>date &gt;&gt; $LOGFILE<\/p>\n<p>Slave KeepAlived &#8212; 141<\/p>\n<p>mkdir -p \/etc\/keepalived\/script\/<\/p>\n<p>cd \/etc\/keepalived\/script\/<\/p>\n<p>[root@localhost script]# cat redis_check.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>ALIVE=`\/usr\/local\/redis\/bin\/redis-cli -a 123456 PING`<\/p>\n<p>if [ &#8220;$ALIVE&#8221; == &#8220;PONG&#8221; ]; then<\/p>\n<p>echo $ALIVE<\/p>\n<p>exit 0<\/p>\n<p>else<\/p>\n<p>echo $ALIVE<\/p>\n<p>exit 1<\/p>\n<p>fi<\/p>\n<p>[root@localhost script]# cat redis_master.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>REDISCLI=&#8221;\/usr\/local\/redis\/bin\/redis-cli -a 123456&#8243;<\/p>\n<p>LOGFILE=&#8221;\/var\/log\/keepalived-redis-state.log&#8221;<\/p>\n<p>echo &#8220;[master]&#8221; &gt;&gt; $LOGFILE<\/p>\n<p>date &gt;&gt; $LOGFILE<\/p>\n<p>echo &#8220;Being master&#8230;.&#8221; &gt;&gt;$LOGFILE 2&gt;&amp;1<\/p>\n<p>echo &#8220;Run SLAVEOF cmd &#8230;&#8221;&gt;&gt; $LOGFILE<\/p>\n<p>$REDISCLI SLAVEOF 172.16.81.140 6379 &gt;&gt;$LOGFILE 2&gt;&amp;1<\/p>\n<p>sleep 10 #<\/p>\n<p>echo &#8220;Run SLAVEOF NO ONE cmd &#8230;&#8221;&gt;&gt; $LOGFILE<\/p>\n<p>$REDISCLI SLAVEOF NO ONE &gt;&gt; $LOGFILE 2&gt;&amp;1<\/p>\n<p>[root@localhost script]# cat redis_backup.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>REDISCLI=&#8221;\/usr\/local\/redis\/bin\/redis-cli -a 123456&#8243;<\/p>\n<p>LOGFILE=&#8221;\/var\/log\/keepalived-redis-state.log&#8221;<\/p>\n<p>echo &#8220;[backup]&#8221; &gt;&gt; $LOGFILE<\/p>\n<p>date &gt;&gt; $LOGFILE<\/p>\n<p>echo &#8220;Being slave&#8230;.&#8221; &gt;&gt;$LOGFILE 2&gt;&amp;1<\/p>\n<p>sleep 15 #<\/p>\n<p>echo &#8220;Run SLAVEOF cmd &#8230;&#8221;&gt;&gt; $LOGFILE<\/p>\n<p>$REDISCLI SLAVEOF 172.16.81.140 6379 &gt;&gt;$LOGFILE 2&gt;&amp;1<\/p>\n<p>[root@localhost script]# cat redis_fault.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>LOGFILE=\/var\/log\/keepalived-redis-state.log<\/p>\n<p>echo &#8220;[fault]&#8221; &gt;&gt; $LOGFILE<\/p>\n<p>date &gt;&gt; $LOGFILE<\/p>\n<p>[root@localhost script]# cat redis_stop.sh<br \/>\n#!\/bin\/bash<\/p>\n<p>LOGFILE=\/var\/log\/keepalived-redis-state.log<\/p>\n<p>echo &#8220;[stop]&#8221; &gt;&gt; $LOGFILE<\/p>\n<p>date &gt;&gt; $LOGFILE<\/p>\n<p>systemctl start keepalived<\/p>\n<p>systemctl enable keepalived<\/p>\n<p>ps -ef | grep keepalived<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Redis master-slave + KeepAlived achieve high availability<\/p>\n<p>Redis is a non-relational database that we currently use more frequently. It can support diverse data types, multi-threaded high concurrency support, and redis running in memory with faster read and write. Because of the excellent performance of redis, how can we ensure that redis can deal with downtime [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[79],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7535"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7535"}],"version-history":[{"count":1,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7535\/revisions"}],"predecessor-version":[{"id":7536,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7535\/revisions\/7536"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}