网站管理助手哪个好用,创作服务平台,菏泽网站建设价格,网站域名解析ip查询http://www.tuicool.com/articles/77nUZn 1、背景 1.1 Redis简介 官方网站#xff1a; http://redis.io/ #xff0c;Redis是REmote DIctionary Server的缩写。 Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库#xff0c;并…http://www.tuicool.com/articles/77nUZn 1、背景 1.1 Redis简介 官方网站 http://redis.io/ Redis是REmote DIctionary Server的缩写。 Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库并提供多种语言的API。从2010年3月15日起Redis的开发工作由VMware主持。它跟 memcached 类似不过数据可以持久化而且支持的数据类型很丰富。它在保持键值数据库简单快捷特点的同时又吸收了部分关系数据库的优点。从而使它的位置处于关系数据库和键值数据库之间。Redis不仅能保存Strings类型的数据还能保存Lists类型有序和Sets类型无序的数据而且还能完成排序SORT等高级功能在实现INCRSETNX等功能的时候保证了其操作的原子性除此以外还支持主从复制等功能。Redis可以被看成是一个数据结构服务器。 Redis的所有数据都是保存在内存中然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”)也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。 1.2 瓶颈 当前卡布西游项目数据存储采用MySQL主游戏库共分为20个库分布在5台机器上每个库数据量约为10G各机器均采用RAID5加速磁盘访问当同时在线人数达到5W时DB磁盘IO压力很大导致游戏卡在线人数再上不去了。而Redis数据读写都是直接操作内存可有效解决这一瓶颈。 1.3 解决方案概述 将部分数据压缩导入到redis后总数据量约15G转换成redis数据类型数据量一主一从模型共两组。一台机器内存32G开20个实例共40个实例预估每个实例最多存储2G数据现在没这么多。多实例方便做持久化。 主库不做AOF也不做快照只在每晚12点计划任务做一次快照并转移到异地。从库开启AOF并1秒落地。 主库每5分钟插入一个时间点crontab实现方便从库AOF记录时间点用于定点还原。 2、安装配置 2.1 硬件配置 Dell R410 32G内存两个CPU每个CPU 4个核心300G硬盘 2.2 安装 a)安装TCMalloc库 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)安装google-perftools wget http://google-perftools.googlecode.com/files/google-perftools-1.8.2.tar.gztar 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)安装redis wget http://redis.googlecode.com/files/redis-2.2.14.tar.gztar xzvf redis-2.2.14.tar.gz cd redis-2.2.14 make USE_TCMALLOCyes //make之后会在 src目录下产生redis-server redis-cli redis-benchmark redis-check-dump 将其拷贝到/usr/local/redis/bin目录下将配置文件redis.conf拷贝到/usr/local/redis/etc目录 //统一建立目录方便管理 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} 检查tcmalloc是否生效 # lsof -n | grep tcmalloc 出现以下信息说明生效 redis-ser 13768 root mem REG 8,5 1616491 788696 /usr/local/lib/libtcmalloc.so.0.1.0 //装完后可能libtcmalloc没有注册没有上面信息在mysqld_safe文件里加一条 export LD_PRELOAD/usr/local/lib/libtcmalloc.so //再重启mysql线上操作谨慎(使用tmalloc内存分配效率更高) 2.3 配置 //当前规划一共开40个实例每台机器20个实例下面以实例01为例 //配置文件名 redis6001.conf ~ redis6040.conf daemonize yespidfile /var/run/redis6001.pidport 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 hash-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.1 主从同步目的目标 主从的主要目的数据持久化灾难恢复冗余。主库不落地减少消耗。 3.2 主从配置 从库安装配置同主库一致主库无需任何改动(允许从库访问)从库需增加两个地方配置slaveof AOF slaveof 192.168.3.180 6301 masterauth My#redis appendonly yes appendfilename appendonly01.aof appendfsync everysec //配置文件名 slave6001.conf ~ slave6040.conf daemonize yespidfile /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 hash-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 备份 备份策略主库每晚12点串行给每个实例做一次快照(bgsave)从库每晚12点串行对AOF文件打包备份(tar)打包备份后做一次AOF文件压缩(bgrewriteaof)。每天的数据起始点是前一天晚上rewriteaof后的数据。 主库每晚12点串行给每个实例做一次快照(bgsave)。主库备份脚本redis_bgsave.sh #!/bin/bash #datedate %y%m%d_%H%M%S REDISPASSWORDMy#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 从库每晚12点串行拷贝每个实例的AOF到其他目录并对其打包压缩包要有异地备份之后再压缩AOFbgrewriteaof。 从库备份AOF并bgrewriteaof脚本redis_backup.sh 对单个实例 #!/bin/sh ## FD:File Dir ## RD:Runing Dir ## 第一个参数为redis实例名 if [ $# -ne 1 ]; then echo “Usage:$0 redis_name” exit fi CURDATEdate %Y%m%d CURHOURdate %Y%m%d_%H CURTIMEdate %Y%m%d_%H%M%S REDISPASSWORDMy#redis REDISNAME$1 PORTecho $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/${REDISNAME}_${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 从库对所有实例备份/data/sh/redis_allbak.sh #!/bin/sh CURDATEdate %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 21 || echo “slave${PORT} backup error” $LOGFILE 21 done 4、操作注意事项 1. 若主库挂了不能直接开启主库程序。若直接开启主库程序将会冲掉从库的AOF文件这样将导致只能恢复到前一天晚上12的备份。 2. 程序在跑时不能重启网络(程序是通过网络接口的端口进行读写的)。网络中断将导致中断期间数据丢失。 3. 确定配置文件全部正确才启动尤其不能有数据文件名相同否则会冲掉原来的文件可能造成无法恢复的损失。 5、灾难恢复 5.1 主库故障快速恢复到最近状态 描述主库挂了redis程序挂了/机器宕机了从库正常恢复到主库挂掉的时间点去从库手动做一次快照拷贝快照到主库相应目录启动OK。 在从库做一次快照转移快照文件到其他目录将快照文件目录拷贝到主库相应目录启动主库OK! ( /data/sh/redis_bgsave_cp.sh ) #!/bin/bash REDISPASSWORDMy#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}/redis${PORT}.rdb #sleep 1 done 在主库将原来数据目录重命名。 从从库拷贝快照文件到主库。 启动主库。 5.2 恢复到当天12点状态 注意备份数据当前状态AOF正常退出快照 停止redis。 解压AOF/data/sh/redis_untar.sh #!/bin/bash DAY20111102 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 切割AOF/data/sh/redis_sed.sh #!/bin/bash DDIR/data/redis_recovery/ TAG”TAG111101_1200″ for PORT in seq 6001 6020 do SDIR/data/backup/redis/20111102_00/ SAOF${SDIR}/slave${PORT}.aof linesed -n “/$TAG/” $SAOF num$[$line 3] mkdir -p ${DDIR}/slave${PORT}/ sed “${num},\$d” $SAOF ${DDIR}/slave${PORT}/slave${PORT}.aof done 将原来数据目录重命名。 将切割出来的AOF目录重命名为配置文件的数据目录。注释主从同步配置项。 启动从库。 做快照拷贝到主库启动主库同5.1。 5.3 恢复到两天或几天前12点状态 从库每晚备份要备份AOF未bgrewriteaof之前的数据可根据当天晚上12点备份没有bfrewriteaof之前的AOF文件来进行恢复方法同5.2。 6、监控 6.1 Nagios监控 # /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:keys2079581,expires0 //监控进程数每台机器redis实例数 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 } //监控主从同步状态获取从库master_link_status与keys的值 //statusdown直接严重警告keys相差10警告keys相差100严重警告 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 } //监控实例内存使用大小1.8G警告2G严重警告 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、资料 7.1 参考资料 Redis入门手册(zh_v1.0).pdf http://www.infoq.com/cn/articles/tq-why-choose-redis // 为什么使用 Redis及其产品定位 http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage // Redis内存使用优化与存储 http://www.infoq.com/cn/articles/tq-redis-copy-build-scalable-cluster // Redis复制与可扩展集群搭建 http://blog.prosight.me/index.php/2011/08/802 // Redis中7种集合类型应用场景 7.2 版本 最新稳定版 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、卡布西游Redis分布 8.1 服务器分布 服务器分布 实例名 端口 … … … 8.2 mysql转redis规则 1.Key命名规则 Key采用字母数字的形式 避免多个应用使用同一个key的时候互相覆盖主项目中的key采用GJ#[UID] 例:GJ12345678 2.字段命名规则 主项目中的key内包含多个字段 代表多个应用 目前给每个应用预留的字段取值范围为100(实际使用中字段不应该超过10个左右不然使用哈希的意义不大了)。 当前的预留字段划分 100~199为成就相关(当前使用150、151 对应MySQL的achieve_user表的history与current字段) 200~299为妖怪相关(当前使用200 对应MySQL的spirit_store表 实际应用时应该会再多2个字段 对应MySQL的spiritmaster与spirit表) 3.实例划分规则 预计将划分40个实例 玩家数据根据玩家的UID取模来分配到不同的实例中(是否再分库未确定) 4.其他使用Redis划分规则 目前庄园也有部分数据使用redis 不过数据是放在一个单独的redis实例中(119.147.164.24) 根据应用不同使用不同的库和key值 Key命名规则为[应用名]-[UID] 例: GrowTimes-12345678 / StolenList-12345678 9、相关测试数据 //测试数据跟存储的数据以及机器硬件配置等有关具体环境可能不太一样仅做参考。 9.1 启动关闭 启动1.6G AOF文件132M RDB启动时间107s产生debug.log 128M使用内存1.71G。 2G数据启动约2分钟主从同步约2分钟(内网)。 关闭shutdown时间很短一般1~2sshutdown之前必须做savesave时间跟数据量有关一般几秒。 9.2 数据量大小 简单setset a 13万条约1M AOF300K RDB12万条约4M AOF1M RDB。 set一条记录AOF会记录些什么 redis set yuwei wangjiancheng *3 $3 set $5 yuwei $3 wangjiancheng 9.3 备份打包 纯文本AOF tar -zcf *.tar.gz * 1.9G / 20s / 16M / tar -jcf *.tar.bz2 * 1.9G / 150s / 5.3M / 当前线上使用redis数据导入是二进制流格式AOF文件为数据文件非文本文件而且导入前已经过一次压缩所以压缩比例很低。 9.4 其他测试 实例配置文件中的数据目录不存在实例无法启动。 AOF边写边打包(tar)不会造成数据损坏tar只是读文件。 Redis运行过程中删除数据目录不能bgsave不能写AOF从库能同步从建目录也不能bgsave不能写AOF。 Bgsave是放后台去执行的所以bgsave;shutdown连写在一起会出问题bgsave还未执行完就已经shutdown了。改用save。 主库实例重启后从库会重新”全同步”一次保存数据与主库一致。 网络闪断不会造成主从数据丢失网络恢复后可以续传。 A实例快照文件放B实例数据目录启动文件名改成B实例数据文件OK! 执行rewriteaof/ bgrewriteaof后reidis根据内存数据重新建立AOFAOF重新排列顺序。 10、客户端连接redis 10.1 PHP 安装phpredis phpredis软件包地址试了N个版本 只有这1个能在我们的定制系统环境装上 蛋疼 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 ## 如果PHP是安装的RPM包需要安装php-devel ./configure –with-php-config/usr/local/php/bin/php-config make make install 配置php.ini vi /usr/local/php/lib/php.ini 加入: extension “redis.so” 重启 fastcgi 生效 /root/fastcgi_restart # php -m //查看是否有redis检查是否安装成功。 Redis扩展测试 测试代码 ?php$redis new Redis();$redis-connect(’127.0.0.1′,6379);$redis-set(‘test’,hello world!’);echo $redis-get(‘test’); ? 返回 hello world 表示成功 ## 密码 $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 这个是官方的库里面有个例子 跑这个带参数 ./hiredis-test 例子应该是test.c 转载于:https://www.cnblogs.com/fvsfvs123/p/4319240.html