Redis Data Storage Solution

Source: Internet
Author: User
Tags syslog

1. Background
1.1 redis Introduction

Official Website: http://redis.io/, redisis the abbreviation of remote dictionary server.

Redis is an open-source log-type and key-value database written in ansi c language that supports Network, memory-based persistence, and provides APIs in multiple languages. From January 1, March 15, 2010, the development of redis was hosted by VMware. It is similar to memcached, but data can be persistent and supports a wide range of data types. It keeps key-value databases simple and fast, while absorbing the advantages of some relational databases. So that it is located between the relational database and the key-value database. Redis not only saves strings data, but also stores lists (ordered) and sets (unordered) data. It also supports advanced functions such as sorting, this ensures the atomicity of operations when implementing functions such as incr and setnx. In addition, it also supports master-slave replication and other functions. Redis can be viewed as a data structure server.

All redis data is stored in the memory and then asynchronously stored to the disk (this is called the "semi-persistent mode "); you can also write every data change to an append only file (AOF) (this is called "Full persistence mode ").
1.2 bottleneck

Currently, in the kabbu xiyou project, data storage uses MySQL. The master game database is divided into 20 databases distributed on five machines, and each database has a data volume of about 10 Gb, each machine uses RAID5 to accelerate disk access. When the number of concurrent online users reaches, the I/O pressure on the DB disk is high, resulting in game cards and the number of online users cannot go up. Redis reads and writes data directly to the memory, which can effectively solve this bottleneck.
1.3 solution Overview

After some data is compressed and imported to redis, the total data volume is about 15 GB (converted to redis data type data volume), one master, one slave model, two groups in total. One machine has 32 GB memory and 20 instances, with a total of 40 instances. It is estimated that each instance can store up to 2 GB of data (not so much now ). Multiple instances facilitate persistence.

The master database does not use aof or snapshots, and only schedules a task at every night and transfers the snapshot to a remote location. Enable aof from the slave database and implement it in 1 second.

A time point (crontab implementation) is inserted to the master database every five minutes to facilitate record time points from the database aof for point restoration.
2. install and configure
2.1 hardware configuration

Dell r410 32 GB memory; two CPUs, 4 cores each; GB hard disk
2.2 Installation

A) install the tcmalloc Library

Source code

Wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz
Tar zxf libunwind-0.99-alpha.tar.gz
CD libunwind-0.99-alpha/
Cflags =-FPIC./configure
Make cflags =-FPIC
Make cflags =-FPIC install

B) install Google-perftools:

Source code

Wget http://google-perftools.googlecode.com/files/google-perftools-1.8.2.tar.gz

Tar zxf google-perftools-1.7.tar.gz

CD google-perftools-1.7/

./Configure

Make

Make install

Echo "/usr/local/lib">/etc/lD. So. conf. d/usr_local_lib.conf

/Sbin/ldconfig

C) install redis

Source code

Wget http://redis.googlecode.com/files/redis-2.2.14.tar.gz

Tar xzvf redis-2.2.14.tar.gz

CD redis-2.2.14

Make use_tcmalloc = Yes

// Make will generate redis-server redis-cli redis-benchmark redis-check-dump in the src directory.

Copy the configuration file redis. conf to the/usr/local/redis/bin directory.

// Create a unified directory for convenient management

Mkdir-P/usr/local/redis/bin

Mkdir-P/usr/local/redis/etc

Mkdir-P/usr/local/redis/var

Mkdir-P/data/redis-Data

# Mkdir-P/data/redis-data/redis60 {01,02, 03,04, 05,06, 07,08, 09,10}

Check whether tcmalloc is effective

# Lsof-N | grep tcmalloc

The following information takes effect:

Redis-Ser 13768 root mem Reg 1616491 788696/usr/local/lib/libtcmalloc. so.0.1.0

// After installation, the libtcmalloc may not be registered and the above information is not found. Add one to the mysqld_safe file:

Export ld_preload =/usr/local/lib/libtcmalloc. so''

// Restart MySQL again (exercise caution when performing online operations !!!) (With tmalloc, the memory allocation efficiency is higher)
2.3 Configuration

// Currently, a total of 40 instances are planned to be created, with 20 instances per machine. The following uses instance 01 as an example:

// Configuration file name: redis6001.conf ~ Redis6040.conf

Source code

Daemonize Yes

Pidfile/var/run/redis6001.pid

Port 6001

Timeout 300

Loglevel debug

Logfile/usr/local/redis/var/debug6001.log

Syslog-enabled Yes

Databases 16

Rdbcompression Yes

Dbfilename redis6001.rdb

DIR/data/redis-data/redis6001

Slave-serve-stale-data Yes

Requirepass my # redis

Appendonly No

No-appendfsync-on-Rewrite No

VM-enabled No

Hhash-max-zipmap-entries 512

Hash-max-zipmap-value 64

List-max-ziplist-entries 512

List-max-ziplist-value 64

Set-max-intset-entries 512

Activerehashing Yes
3. Master-slave synchronous backup and related scripts
3.1 master-slave synchronization target

The main objective of Master/Slave is data persistence, disaster recovery, and redundancy. The master database is not implemented, reducing consumption.
3.2 Master/Slave Configuration

The slave database installation configuration is consistent with that of the master database. The master database does not need to be modified (Allow access from the slave database). The slave database requires two additional configurations: slaveof + Aof.

Slaveof 192.168.3.180 6301

Masterauth my # redis

Appendonly Yes

Appendfilename appendonly01.aof

Appendfsync everysec

// Configuration file name: slave6001.conf ~ Slave6040.conf

Source code

Daemonize Yes

Pidfile/var/run/slave6001.pid

Port 6001

Timeout 300

Loglevel debug

Logfile/usr/local/redis/var/debug6001.log

Syslog-enabled Yes

Databases 16

Rdbcompression Yes

Dbfilename slave6001.rdb

DIR/data/redis-data/slave6001

Slaveof 192.168.0.139 6001

Masterauth my # redis

Slave-serve-stale-data Yes

Requirepass my # redis

Appendonly Yes

Appendfilename slave6001.aof

Appendfsync everysec

No-appendfsync-on-Rewrite No

VM-enabled No

VM-Swap-file/tmp/redis. Swap

VM-max-memory 0

VM-page-size 32

VM-pages 134217728

VM-max-threads 4

Hhash-max-zipmap-entries 512

Hash-max-zipmap-value 64

List-max-ziplist-entries 512

List-max-ziplist-value 64

Set-max-intset-entries 512

Activerehashing Yes
3.3 backup

Backup policy: the master database serializes a snapshot (bgsave) to each instance at every night. The aof file is packaged and backed up (TAR) from the database at each night ), after packaging and backup, compress the aof file (bgrewriteaof ). The starting point of each day is the data after rewriteaof the previous night.

The master database takes a snapshot (bgsave) for each instance at every night ). Master database backup script (redis_bgsave.sh)

#! /Bin/bash

# Date = 'date + % Y % m % d _ % H % m % s'

Redispassword = My # redis

For port in 'seq 6001 6020'

Do

/Usr/local/redis/bin/redis-cli-H 127.0.0.1-p $ Port-A $ redispassword bgsave

Sleep 10

Done

Date>/usr/local/redis/var/bgsave. Log

Copy the AOF of each instance to another directory and package it at each night. The compressed package must have a remote backup, and then compress the aof (bgrewriteaof ).

Back up the aof and bgrewriteaof script from the database (redis_backup.sh: for a single instance)

#! /Bin/sh

# FD: file dir

# RD: runing dir

# The first parameter is the redis Instance name

If [$ #-ne 1]; then

Echo "Usage: $0 redis_name"

Exit

Fi

Curdate = 'date + % Y % m % d'

Curhour = 'date + % Y % m % d _ % H'

Curtime = 'date + % Y % m % d _ % H % m % s'

Redispassword = My # redis

Redisname = $1

Port = 'echo $ redisname | cut-c6-9'

Logfile =/data/logs/redisbak/redis_allbak _ $ {curdate}. Log

If ["$ {redisname}" = ""]; then

Echo "redis name Error !"

Exit 1

Else

If [! -D "/data/redis-data/$ {redisname}"]; then

Echo "redis name Error !"

Exit 1

Fi

Fi

Ddir =/data/backup/redis/$ curhour

Mkdir-p $ {ddir}

Rdir =/data/redis-data/$ redisname

CD $ {rdir}

Tar-zcf $ ddir/zookeeper redisname1__zookeeper curtime=.tar.gz $ redisname. aof

If [$? ! = 0]; then

Echo "tar error $ redisname. aof" >>$ logfile

# Exit 1

Fi

Sleep 5

/Usr/local/redis/bin/redis-cli-H 127.0.0.1-p $ Port-A $ redispassword bgrewriteaof

Sleep 5

### Delete old backup data dir ###

#/Bin/Rm-RF 'date-D-7day + "% Y % m % d "'

Find/data/backup/redis/-mtime + 7 | xargs Rm-RF

Echo "backup $ redisname OK at $ curtime !" >>$ Logfile

Back up all instances from the slave database (/data/SH/redis_allbak.sh)

#! /Bin/sh

Curdate = 'date + % Y % m % d'

Logfile =/data/logs/redisbak/redis_allbak _ $ {curdate}. Log

For port in 'seq 6001 6020'

Do

/Data/SH/redis_backup.sh slave $ {port} & Echo "Slave $ {port} OK 'date + % Y % m % d _ % H % m % s'">> $ logfile 2> & 1 | echo "Slave $ {port} backup error" >>$ logfile 2> & 1

Done
4. Operation precautions

If the master database crashes, the master database program cannot be started directly. If the master database program is enabled directly, the aof file from the slave database will be flushed out. This will only cause the backup to be restored to 12 of the previous night.

When a program is running, the network cannot be restarted (the program reads and writes through the port of the network interface ). Network interruption may cause data loss during the interruption.

Make sure that all the configuration files are correct before starting (especially if the file names are not the same). Otherwise, the original file will be washed out, which may cause irreparable loss.

5. Disaster Recovery
5.1 master database faults, quickly restoring to the nearest state

Description: when the master database is down (the redis program is down/the machine is down) and the database is normal and recovered to the time when the master database is down: manually taking a snapshot from the slave database, copy the snapshot to the corresponding directory of the master database, start, OK.

Take a snapshot from the slave database, transfer the snapshot file to another directory, copy the snapshot file directory to the corresponding directory of the master database, and start the master database. OK!

(/Data/SH/redis_bgsave_cp.sh)

#! /Bin/bash

Redispassword = My # redis

For port in 'seq 6001 6020'

Do

/Usr/local/redis/bin/redis-cli-H 127.0.0.1-p $ Port-A $ redispassword bgsave

Sleep 5

Done

Sleep 15

For port in 'seq 6001 6020'

Do

Sdir =/data/redis-data/Slave $ {port }/

Ddir =/data/redis_recovery/redis-data/

Mkdir-p $ ddir/redis $ {port }/

CD $ sdir

CP-RF slave $ {port}. RDB $ ddir/redis $ {port}. RDB

# Sleep 1

Done

Rename the original data directory in the master database.

Copy the snapshot file from the slave database to the master database.

Start the master database.
5.2 restore to on the current day

Pay attention to data backup (current status aof + normal exit snapshot )!

Stop redis.

Decompress aof (/data/SH/redis_untar.sh)

#! /Bin/bash

Day = 20111102

Sdir =/data/backup/redis/20111102_00/

CD $ sdir

For port in 'seq 6001 6020'

Do

Tar-zxf slave $ {port} $ day * .tar.gz

Sleep 2

Done

Cut aof (/data/SH/redis_sed.sh)

#! /Bin/bash

Ddir =/data/redis_recovery/

Tag = "tag1111000001200 ″

For port in 'seq 6001 6020'

Do

Sdir =/data/backup/redis/20111102_00/

Saof =$ {sdir}/Slave $ {port}. aof

Line = 'sed-n "/$ tag/=" $ saof'

Num = $ [$ line + 3]

Mkdir-p $ {ddir}/Slave $ {port }/

Sed "$ {num}, \ $ D" $ saof >$ {ddir}/Slave $ {port}. aof

Done

Rename the original data directory.

Rename the cut aof directory to the data directory of the configuration file. (Comment out the master-slave synchronization configuration items ).

Start slave database.

Create a snapshot, copy the snapshot to the master database, and start the master database (same as 5.1 ).
5.3 restore to the status of two days or a few days ago

Back up data before aof without bgrewriteaof from the database every night. You can back up data at that night and restore the aof file without bfrewriteaof. The method is the same as 5.2.
6. Monitoring
6.1 Nagios monitoring

#/Usr/local/redis/bin/redis-cli-H 127.0.0.1-P 6301-a my # redis info

Used_memory_human: 1.49g

Master_link_status: down up/down

Db0: Keys = 2079581, expires = 0

// Monitor the number of processes (the number of redis instances on each machine)

Define Service {

Use local-Service

Host_name 119.147.163.xxx

Servicegroups procs

Service_description redis_20

Check_command check_nrpe! Check_procs \! 20:20 \! 20:25 \! Redis-Server

}

// Monitor the master-slave synchronization status (obtain the values of master_link_status and keys from the slave database)

// Status = down direct severe warning, keys difference 10 warning, keys difference 100 severe warning

Define Service {

Use local-Service

# Hostgroup_name kabuxiyou

Host_name 119.147.161.xxx

Servicegroups redis

Service_description redis_239

Check_command check_nrpe! Check_redis_slave \! 192.168.0.139 \! 6379 \! 127.0.0.1 \! 6380

}

// Monitor the memory usage of the instance, with a warning of GB and a severe warning of 2 GB

Define Service {

Use local-Service

# Hostgroup_name kabuxiyou

Host_name 119.147.161.xxx

Servicegroups redis

Service_description redis_mem_22

Check_command check_nrpe! Check_redis_mem \! 127.0.0.1 \! 6381

}
7. Materials
7.1 references

// Redis manual (zh_v1.0133

Http://www.infoq.com/cn/articles/tq-why-choose-redis

// Why use redis and its product positioning

Http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage

// Redis memory usage optimization and storage

Http://www.infoq.com/cn/articles/tq-redis-copy-build-scalable-cluster

// Redis replication and Scalable Cluster Creation

Http://blog.prosight.me/index.php/2011/08/802

// Seven Collection types of application scenarios in redis
Version 7.2

Latest stable version:

Wget http://redis.googlecode.com/files/redis-2.2.14.tar.gz // 2011.10.1

Wget http://redis.googlecode.com/files/redis-2.4.2.tar.gz // 2011.11.15

Wget http://redis.googlecode.com/files/redis-2.4.10.tar.gz // 2012.04.16
8. apsaradb for redis Distribution
8.1 Server distribution

Server distribution: Instance name: Port:

... ... ...
8.2 rules for conversion from MySQL to redis

1. Key naming rules

The key is in the form of letters and numbers to prevent multiple applications from overwriting each other when using the same key. The key in the main project adopts GJ # [uid] example: gj12345678

2. Field naming rules

The key in the main project contains multiple fields, which indicates that the value range of the fields currently reserved for each application by multiple applications is 100. (in actual use, the number of fields should not exceed 10. Otherwise, hash is of little significance. ).

Current reserved field division:

100 ~ 199 is related to achievements (currently, the history and current fields in the achieve_user table of MySQL 150 and 151 are used)

200 ~ 299 is related to monsters (currently, two more fields corresponding to MySQL's spirit_store table correspond to MySQL's spiritmaster and spirit tables)

3. Instance Division rules

It is estimated that the gamer data will be divided into 40 instances and allocated to different instances based on the player's uid modulo (whether to split the database or not is unknown)

4. Other rules for using redis

At present, the manor also has some data using redis, but the data is placed in a separate redis instance (119.147.164.24)

Use different library and key value Key naming rules for different applications as [Application name]-[uid] example: GrowTimes-12345678/StolenList-12345678
9. Test Data

// The test data is related to the stored data and the hardware configuration of the machine. The specific environment may be different.
9.1 close startup

Start: 1.6g aof file, 132 m rdb, start time 107 s, Generate debug. Log 128 M, use memory 1.71G.

2G data, start for about 2 minutes, master-slave synchronization for about 2 minutes (Intranet ).

Close: shutdown is very short, generally 1 ~ 2 S. Save is required before shutdown. The save time is related to the data volume, generally several seconds.
9.2 data size

Simple set (set a 1), 30 thousand treaty 1 m aof, 300 k rdb, 0.12 million Treaty 4 m aof, 1 m RDB.

Set a record. What does aof record:

Redis> set yuwei wangjiancheng

* 3

$3

Set

$5

Yuwei

$3

Wangjiancheng

9.3 backup Packaging

Plain text aof:

Tar-zcf * .tar.gz * 1.9g/20 s/16 m/

Tar-JCF * .tar.bz2*1.9g/150 s/5.3 m/

Currently, apsaradb for redis is used online. Data Import is in the binary stream format (AOF files are data files and non-text files). Compression has been performed before the import, so the compression ratio is very low.
9.4 other tests

The data directory in the instance configuration file does not exist and the instance cannot be started.

Aof writes and packs (TAR) without causing data corruption. Tar only reads files.

When redis is running, the data directory cannot be deleted, bgsave, aof cannot be written, and slave database can be synchronized; bgsave cannot be created, and aof cannot be written.

Bgsave is executed in the background. Therefore, a problem occurs when bgsave and shutdown are written together. bgsave has been shutdown since it has not been executed. Use save instead.

After the master database instance is restarted, the slave database will be "fully synchronized" again to save the same data as the master database.

Transient network disconnection does not cause loss of Master/Slave Data, and can be resumed after the network recovers.

Instance a snapshot file, put instance B data directory to start (file name changed to instance B data file), OK!

After rewriteaof/bgrewriteaof is executed, reidis re-creates aof and aof re-arranges the order based on the memory data.
10. Connect the client to redis
10.1 PHP

Install phpredis:

Phpredis package address (N versions have been tried. Only one of them can be installed in our custom system environment)

Http://ftp.nluug.nl/pub/NetBSD/packages/distfiles/php-redis/nicolasff-phpredis-2.1.3-0-g43bc590.tar.gz

CD/Dist/src

Tar xzf ../Dist/nicolasff-phpredis-2.1.3-0-g43bc590.tar.gz

CD nicolasff-phpredis-43bc590

/Usr/local/PHP/bin/phpize

# If PHP is an installed RPM package, you need to install PHP-devel

./Configure-with-PHP-Config =/usr/local/PHP/bin/PHP-config

Make & make install

Configure PHP. ini

VI/usr/local/PHP/lib/PHP. ini: Extension = "redis. So"

Restart FastCGI to take effect/root/fastcgi_restart # PHP-M // check whether redis exists and whether the installation is successful.

Redis Extension Test

Test code:

<? PHP $ redis = new redis (); $ redis-> connect ('127. 0.0.1 ', 127); $ redis-> set ('test', 'Hello world! '); Echo $ redis-> get ('test ');

?>

Return Hello world! Success

# Password

$ Redis-> auth ('My # redis ');

# Error:

Configure: Error: invalid value of Canonical build

#./Configure

./Configure-with-PHP-Config =/usr/local/PHP/bin/PHP-config

10.2 C ++

Antirez-hiredis-3cc6a7f.tar.gz 340 KB

This is the official library, which contains an example

Run this command with parameters./hiredis-test

The example is test. C.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.