Redis主从架构持久化存在一个问题,即前次测试的结论,持久化需要配置在主实例上才能跨越实例保证数据不丢失,这样以来主实例在持久化数据到硬盘的过程中,势必会造成磁盘的I/O等待,经过实际测试,这个持久化写硬盘的过程给应用程序带来的影响无法忍受;因而在大多数场景下,会考虑把持久化配置在从实例上,当主实例宕机后,通过手动或者自动的方式将从实例提升为主实例,继续提供服务!当主实例恢复后,先从原从实例上同步数据,同步完成后再恢复到原始的主从状态!要实现这种的要求,需要有keepalive的配合,一方面keepalive提供了VIP,可以避免修改应用程序连接,同时redis实例的配置文件监听部分也需要修改为全网监听;另一方面keepalive定时调度脚本来监控主从实例的状态,根据具体情况进行切换!本文将重点介绍下使用keepalive实现redis主从自动failover!

环境介绍
操作系统版本均为:rhel5.4 64bit
redis版本:2.6.4
redis实例端口均为:6379
redis实例密码均为:123
VIP:192.168.1.120
主实例为server11(192.168.1.112)
从实例为server12(192.168.1.113,开启快照持久化)

一:安装keepalive软件,server11安装完成后直接scp至server12上即可

  1. [root@server11 ~]# wget http://keepalived.org/software/keepalived-1.1.19.tar.gz
  2. [root@server11 ~]# tar -zxvf ../tarbag/keepalived-1.1.19.tar.gz
  3. [root@server11 ~]# cd keepalived-1.1.19/
  4. [root@server11 ~]# ./configure --prefix=/usr/local/keepalived && make && make install

二:配置主节点server11配置文件

  1. [root@server11 ~]# cat /usr/local/keepalived/etc/keepalived/keepalived.conf
  2. ! Configuration File for keepalived
  3. global_defs {
  4. router_id LVS_DEVEL
  5. }
  6. vrrp_script Monitor_redis {
  7. script "/usr/local/scripts/redis_monitor.sh"
  8. interval 2
  9. weight 2
  10. }
  11. vrrp_instance VI_1{
  12. state MASTER
  13. interface eth0
  14. virtual_router_id 51
  15. mcast_src_ip 192.168.1.112
  16. priority  100
  17. advert_int 1
  18. authentication {
  19. auth_type PASS
  20. auth_pass password_123
  21. }
  22. track_script {
  23. Monitor_redis
  24. }
  25. virtual_ipaddress {
  26. 192.168.1.120
  27. }
  28. notify_fault  /usr/local/scripts/redis_fault.sh
  29. notify_stop   /usr/local/scripts/redis_stop.sh
  30. }

三:配置从节点server12配置文件

  1. [root@server12 ~]# cat /usr/local/keepalived/etc/keepalived/keepalived.conf
  2. ! Configuration File for keepalived
  3. global_defs {
  4. router_id LVS_DEVEL
  5. }
  6. vrrp_script Monitor_redis {
  7. script "/usr/local/scripts/redis_monitor.sh"
  8. interval 2
  9. weight 2
  10. }
  11. vrrp_instance VI_1{
  12. state BACKUP
  13. interface eth0
  14. virtual_router_id 51
  15. mcast_src_ip 192.168.1.113
  16. priority  99
  17. advert_int 1
  18. authentication {
  19. auth_type PASS
  20. auth_pass password_123
  21. }
  22. track_script {
  23. Monitor_redis
  24. }
  25. virtual_ipaddress {
  26. 192.168.1.120
  27. }
  28. notify_master /usr/local/scripts/redis_master.sh
  29. notify_backup /usr/local/scripts/redis_backup.sh
  30. notify_fault  /usr/local/scripts/redis_fault.sh
  31. notify_stop   /usr/local/scripts/redis_stop.sh
  32. }

四:准备相关的脚本,主从实例上都需要存在这些脚本,同时注意脚本需要由可执行权限

  1. [root@server11 ~]# cat /usr/local/scripts/redis_monitor.sh
  2. #!/bin/bash
  3. ALIVE=$(/usr/local/redis2/bin/redis-cli -h 192.168.1.112 -p 6379 -a 123 PING)
  4. if [ "$ALIVE" == "PONG" ]; then
  5. echo $ALIVE
  6. exit 0
  7. else
  8. echo $ALIVE
  9. killall -9 keepalived
  10. service network restart
  11. exit 1
  12. fi
  13. [root@server11 ~]# sh /usr/local/scripts/redis_monitor.sh
  14. PONG
  15. [root@server11 ~]# cat /usr/local/scripts/redis_master.sh
  16. #!/bin/bash
  17. REDISCLI="/usr/local/redis2/bin/redis-cli -h 192.168.1.112 -p 6379 -a 123"
  18. LOGFILE="/usr/local/redis2/var/keepalived-redis-state.log"
  19. echo "[master]" >> $LOGFILE
  20. date >> $LOGFILE
  21. echo "Being master...." >> $LOGFILE 2>&1
  22. echo "Run SLAVEOF cmd ..." >> $LOGFILE
  23. $REDISCLI SLAVEOF 192.168.1.113 6379 >> $LOGFILE  2>&1
  24. sleep 10
  25. echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
  26. $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
  27. [root@server11 ~]# cat /usr/local/scripts/redis_backup.sh
  28. #!/bin/bash
  29. REDISCLI="/usr/local/redis2/bin/redis-cli -h 192.168.1.112 -p 6379 -a 123"
  30. LOGFILE="/usr/local/redis2/var/keepalived-redis-state.log"
  31. echo "[backup]" >> $LOGFILE
  32. date >> $LOGFILE
  33. echo "Being slave...." >> $LOGFILE 2>&1
  34. sleep 15
  35. echo "Run SLAVEOF cmd ..." >> $LOGFILE
  36. $REDISCLI SLAVEOF 192.168.1.113 6379 >> $LOGFILE  2>&1
  37. [root@server11 ~]# cat /usr/local/scripts/redis_stop.sh
  38. #!/bin/bash
  39. LOGFILE="/usr/local/redis2/var/keepalived-redis-state.log"
  40. echo "[stop]" >> $LOGFILE
  41. date >> $LOGFILE
  42. [root@server11 ~]# cat /usr/local/scripts/redis_fault.sh
    #!/bin/bash 
    LOGFILE="/usr/local/redis2/var/keepalived-redis-state.log"
    echo "[fault]" >> $LOGFILE 
    date >> $LOGFILE

五:主从实例分别启动keepalive进程,测试VIP是否正常(这里就要修改redis配置文件的监听地址为0.0.0.0)

  1. [root@server11 ~]# /usr/local/keepalived/sbin/keepalived -D -f  /usr/local/keepalived/etc/keepalived/keepalived.conf
  2. [root@server11 ~]# tail -f /var/log/messages
  3. Dec 12 09:25:49 server11 Keepalived_healthcheckers[7710]: Configuration is using : 5499 Bytes
  4. Dec 12 09:25:49 server11 Keepalived_healthcheckers[7710]: Using LinkWatch kernel netlink reflector...
  5. Dec 12 09:25:49 server11 Keepalived_vrrp[7712]: VRRP sockpool: [ifindex(2), proto(112), fd(12,13)]
  6. Dec 12 09:25:49 server11 Keepalived_vrrp[7712]: VRRP_Script(Monitor_redis) succeeded
  7. Dec 12 09:25:50 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) Transition to MASTER STATE
  8. Dec 12 09:25:51 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) Entering MASTER STATE
  9. Dec 12 09:25:51 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) setting protocol VIPs.
  10. Dec 12 09:25:51 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
  11. Dec 12 09:25:51 server11 avahi-daemon[4519]: Registering new address record for 192.168.1.120 on eth0.
  12. Dec 12 09:25:51 server11 Keepalived_healthcheckers[7710]: Netlink reflector reports IP 192.168.1.120 added
  13. Dec 12 09:25:51 server11 Keepalived_vrrp[7712]: Netlink reflector reports IP 192.168.1.120 added
  14. Dec 12 09:25:56 server11 Keepalived_vrrp[7712]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
  15. [root@server11 ~]# ip a |grep 192
  16. inet 192.168.1.112/24 brd 192.168.1.255 scope global eth0
  17. inet 192.168.1.120/32 scope global eth0
  18. [root@server12 ~]# /usr/local/keepalived/sbin/keepalived -D -f /usr/local/keepalived/etc/keepalived/keepalived.conf
  19. [root@server12 ~]# tail -f /var/log/messages
  20. Dec 12 09:26:55 server12 Keepalived_healthcheckers[3106]: Configuration is using : 5595 Bytes
  21. Dec 12 09:26:55 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Entering BACKUP STATE
  22. Dec 12 09:26:55 server12 Keepalived_healthcheckers[3106]: Using LinkWatch kernel netlink reflector...
  23. Dec 12 09:26:55 server12 Keepalived_vrrp[3108]: VRRP sockpool: [ifindex(2), proto(112), fd(12,13)]
  24. Dec 12 09:26:55 server12 Keepalived_vrrp[3108]: VRRP_Script(Monitor_redis) succeeded
  25. [root@server11 ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |grep -A 3 'Replication'
  26. # Replication
  27. role:master
  28. connected_slaves:1
  29. slave0:192.168.1.113,6379,online

六:主实例写入测试数据,该脚本原则上会写入25条测试数据,不过由于未优化redis默认并发数,会导致一些写入请求失败,最终功写入231839条测试数据,占内存总大小为25M左右,写入过程中可以观察主从实例的持久化文件变化情况,主实例的持久化文件维持在30k,从实例的则不断的扩展!

  1. [root@server11 ~]# cat test.sh
  2. #!/bin/bash
  3. REDISCLI="/usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 -n 1 SET"
  4. ID=1
  5. while(($ID<50001))
  6. do
  7. INSTANCE_NAME="i-2-$ID-VM"
  8. UUID=`cat /proc/sys/kernel/random/uuid`
  9. PRIVATE_IP_ADDRESS=10.`echo "$RANDOM % 255 + 1" | bc`.`echo "$RANDOM % 255 + 1" | bc`.`echo
  10. "$RANDOM % 255 + 1" | bc`\
  11. CREATED=`date "+%Y-%m-%d %H:%M:%S"`
  12. $REDISCLI vm_instance:$ID:instance_name "$INSTANCE_NAME"
  13. $REDISCLI vm_instance:$ID:uuid "$UUID"
  14. $REDISCLI vm_instance:$ID:private_ip_address "$PRIVATE_IP_ADDRESS"
  15. $REDISCLI vm_instance:$ID:created "$CREATED"
  16. $REDISCLI vm_instance:$INSTANCE_NAME:id "$ID"
  17. ID=$(($ID+1))
  18. done
  19. [root@server11 ~]# sh test.sh
  20. [root@server11 redis2]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |egrep
  21. 'used_memory_peak_human|db1:keys'
  22. used_memory_peak_human:24.98M
  23. db1:keys=231839,expires=0

七:模拟主实例故障,观察日志输出,验证从实例是否能成功接管VIP,同时将实例变成读写模式

  1. [root@server11 ~]# killall -9  redis-server
  2. [root@server11 ~]# ip a |grep 192
  3. inet 192.168.1.112/24 brd 192.168.1.255 scope global eth0
  4. [root@server11 ~]# ps -ef |grep redis
  5. root     15886  6458  0 09:49 pts/0    00:00:00 grep redis
  6. [root@server11 ~]# ps -ef |grep keep
  7. root     16029  6458  0 09:49 pts/0    00:00:00 grep keep
  8. [root@server12 ~]# tail -f /usr/local/redis2/var/keepalived-redis-state.log
  9. [master]
  10. Wed Dec 12 09:48:52 CST 2012
  11. Being master....
  12. Run SLAVEOF cmd ...
  13. OK Already connected to specified master
  14. Run SLAVEOF NO ONE cmd ...
  15. OK
  16. [root@server12 ~]# tail -f /var/log/messages
  17. Dec 12 09:48:51 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Transition to MASTER STATE
  18. Dec 12 09:48:52 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Entering MASTER STATE
  19. Dec 12 09:48:52 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) setting protocol VIPs.
  20. Dec 12 09:48:52 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
  21. Dec 12 09:48:52 server12 Keepalived_vrrp[3108]: Netlink reflector reports IP 192.168.1.120 added
  22. Dec 12 09:48:52 server12 avahi-daemon[2921]: Registering new address record for 192.168.1.120 on eth0.
  23. Dec 12 09:48:52 server12 Keepalived_healthcheckers[3106]: Netlink reflector reports IP 192.168.1.120 added
  24. Dec 12 09:48:57 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
  25. [root@server12 ~]# ip a |grep 192
  26. inet 192.168.1.113/24 brd 192.168.1.255 scope global eth0
  27. inet 192.168.1.120/32 scope global eth0
  28. [root@server12 ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |grep -A 3 'Replication'
  29. # Replication
  30. role:master
  31. connected_slaves:0

八:继续使用脚本写入测试数据,通过重复运行脚本更新记录,这次成功写入了249925条测试数据

  1. [root@server12 ~]# sh test.sh
  2. [root@server12 ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |egrep
  3. 'used_memory_peak_human|db1:keys'
  4. used_memory_peak_human:26.78M
  5. db1:keys=249925,expires=0

九:主实例角色的恢复过程,使用shell脚本自动恢复

  1. [root@server11 ~]# ssh-keygen
  2. [root@server11 ~]# cd .ssh/
  3. [root@server11 .ssh]# ssh-copy-id -i id_rsa.pub root@192.168.1.113
  4. [root@server11 ~]# cat /usr/local/scripts/recover_mastart.sh
  5. #!/bin/sh
  6. ALIVE=$(/usr/local/redis2/bin/redis-cli -h 192.168.1.113 -p 6379 -a 123 PING)
  7. MDB=/usr/local/redis2/master_dump.rdb
  8. SDB=/usr/local/redis2/slave_dump.rdb
  9. if [ "$ALIVE" == "PONG" ]; then
  10. echo $ALIVE
  11. scp root@192.168.1.113:$SDB  $MDB
  12. else
  13. echo $ALIVE
  14. exit 1
  15. fi
  16. /usr/local/redis2/bin/redis-server /usr/local/redis2/etc/redis.conf
  17. /usr/local/keepalived/sbin/keepalived -D -f
  18. /usr/local/keepalived/etc/keepalived/keepalived.conf
  19. [root@server11 ~]# chmod +x  /usr/local/scripts/recover_mastart.sh
  20. [root@server11 ~]# sh /usr/local/scripts/recover_mastart.sh

十:验证数据完整性和主从角色恢复情况

  1. [root@server11 ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |egrep 'used_memory_peak_human|db1:keys'
  2. used_memory_peak_human:26.78M
  3. db1:keys=249925,expires=0
  4. [root@server11 ~]#  /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |grep -A 3 'Replication'
  5. # Replication
  6. role:master
  7. connected_slaves:1
  8. slave0:192.168.1.113,6379,online
  9. [root@server12 ~]#  /usr/local/redis2/bin/redis-cli -h 192.168.1.113 -a 123 info |grep -A 3 'Replication'
  10. # Replication
  11. role:slave
  12. master_host:192.168.1.112
  13. master_port:6379
  14. [root@server12 ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.120 -a 123 info |egrep 'used_memory_peak_human|db1:keys'
  15. used_memory_peak_human:26.78M
  16. db1:keys=249925,expires=0
  17. 主实例keepalive日志:
  18. [root@server11 ~]# tail -f /var/log/messages
  19. Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP sockpool: [ifindex(2), proto(112), fd(11,12)]
  20. Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP_Script(Monitor_redis) succeeded
  21. Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Transition to MASTER STATE
  22. Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Received higher prio advert
  23. Dec 12 10:08:13 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Entering BACKUP STATE
  24. Dec 12 10:08:15 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) forcing a new MASTER election
  25. Dec 12 10:08:16 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Transition to MASTER STATE
  26. Dec 12 10:08:17 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Entering MASTER STATE
  27. Dec 12 10:08:17 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) setting protocol VIPs.
  28. Dec 12 10:08:17 server11 Keepalived_healthcheckers[20230]: Netlink reflector reports IP 192.168.1.120 added
  29. Dec 12 10:08:17 server11 Keepalived_vrrp[20231]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
  30. Dec 12 10:08:17 server11 Keepalived_vrrp[20231]: Netlink reflector reports IP 192.168.1.120 added
  31. Dec 12 10:08:17 server11 avahi-daemon[4519]: Registering new address record for 192.168.1.120 on eth0.
  32. [root@server11 ~]# ip a |grep 192
  33. inet 192.168.1.112/24 brd 192.168.1.255 scope global eth0
  34. inet 192.168.1.120/32 scope global eth0
  35. 从实例keepalive日志:
  36. [root@server12 ~]# tail -f /var/log/messages
  37. Dec 12 09:56:01 server12 last message repeated 4 times
  38. Dec 12 10:08:13 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Received lower prio advert, forcing new election
  39. Dec 12 10:08:13 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Sending gratuitous ARPs on eth0 for 192.168.1.120
  40. Dec 12 10:08:15 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Received higher prio advert
  41. Dec 12 10:08:15 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) Entering BACKUP STATE
  42. Dec 12 10:08:15 server12 Keepalived_vrrp[3108]: VRRP_Instance(VI_1{) removing protocol VIPs.
  43. Dec 12 10:08:15 server12 Keepalived_healthcheckers[3106]: Netlink reflector reports IP 192.168.1.120 removed
  44. Dec 12 10:08:15 server12 Keepalived_vrrp[3108]: Netlink reflector reports IP 192.168.1.120 removed
  45. Dec 12 10:08:15 server12 avahi-daemon[2921]: Withdrawing address record for 192.168.1.120 on eth0.
  46. 从实例角色转换日志:
  47. [root@server12 ~]# tail -f /usr/local/redis2/var/keepalived-redis-state.log
  48. [backup]
  49. Wed Dec 12 10:08:15 CST 2012
  50. Being slave....
  51. Run SLAVEOF cmd ...
  52. OK

参考文档:
http://heylinux.com/archives/1932.html

Redis主从自动failover相关推荐

  1. (六)Redis主从自动恢复-sentinel

    原文地址,转载请注明出处: http://blog.csdn.net/qq_34021712/article/details/72026313     ©王赛超 准备工作:(1个master,2个sl ...

  2. php redis主从自动切换,Redis 集群的主从切换

    Redis 集群的主从切换不再使用 Sentinel 作为外置监控, 而是集群内部在主节点挂掉之后选举出一个从节点取代主节点, 处理相应的分片的数据请求. 当然前提条件是对应的主节点有至少一个可连通的 ...

  3. Linux企业化运维--(7)redis服务之redis配置及主从复制、主从自动切换、集群、redis+mysql、gearman实现数据同步

    Linux企业化运维 实验所用系统为Redhat-rhel7.6. 目录 Linux企业化运维 Linux企业化运维--(7)redis服务之redis配置及主从复制.主从自动切换.集群.redis+ ...

  4. redis的主从自动切换

    设置redis主从主要是在不同的主机上编辑配置文件 我们准备三台主机 分别是server1.server2.server3 redis的主从自动切换是基于sentinel(哨兵) 1.Redis 的 ...

  5. Redis主从配置及通过Keepalived实现Redis自动切换高可用

    Redis主从配置及通过Keepalived实现Redis自动切换高可用 [日期:2014-07-23] 来源:Linux社区  作者:fuquanjun [字体:大 中 小] 一:环境介绍: Mas ...

  6. redis sentinel 主从切换(failover)解决方案,详细配置

    主从复制简单来说就是把一台redis数据库中的数据同步到另一台redis数据库,并且按照数据流向,数据的发送者我们称作master,数据的接受者我们称作slave(master/slave的划分并不是 ...

  7. 【Redis3】基于Redis sentinel的自动failover主从复制

    [Redis3]基于Redis sentinel的自动failover主从复制 在第二篇中使用2.8.17搭建了主从复制,但是它存在Master单点问题,为了解决这个问题,Redis从2.6开始引入s ...

  8. 【带你重拾Redis】Redis 主从架构

    Redis 主从架构 单机的 Redis,能够承载的 QPS 大概就在上万到几万不等.对于缓存来说,一般都是用来支撑读高并发的.因此架构做成主从(master-slave)架构,一主多从,主负责写,并 ...

  9. Redis 主从集群搭建及哨兵模式配置

    Redis 主从集群搭建及哨兵模式配置 最近搭建了redis集群及哨兵模式,为方便以后查看特此记录下来: 1.Redis安装 2.主从架构 2.1 Redis主从架构图 2.2Redis主从结构搭建 ...

最新文章

  1. php不报错怎么回事,解决PHP 7等web编程语言不报错一例
  2. codeforce 570 problem E 51Nod-1503-猪和回文
  3. vb编程的好帮手--资源文件
  4. python输入hello*3_python入门到实践-Hello Python3
  5. 对计算机网络设备的认识,计算机入门知识:你有必要认识的网络设备及工具
  6. 前端学习(2242)以组件方式创建UI
  7. Shiro框架-史上详解
  8. 龙芯电脑使用Loongnix系统
  9. 对比分析163VIP邮箱费用,原来有这么多的好处!
  10. csv文件用excel打开乱码问题
  11. ueditor+实现word图片自动上传
  12. 从微信公众号获取关注名单
  13. grafana repeat 特性
  14. 汽车VIN编号 有效性检查 PHP 验证算法
  15. AndroidStudio连接真机测试运行
  16. 最新微软薪资曝光,Run去美国还是好选择吗?
  17. 华数机器人码垛_华数工业机器人码垛路径操作教程
  18. 终极算法——第七章:类推学派:像什么就是什么
  19. 通过u盘启动计算机使用ghost安装系统步骤,如何用u盘装ghost win7系统步骤
  20. 27.python-网路-tcp

热门文章

  1. 十、Python-模块
  2. 进阶!基于CentOS7系统使用cobbler实现单台服务器批量自动化安装不同版本系统(week3_day5_part2)-技术流ken...
  3. 1100名达摩院“扫地僧”加持,阿里云的下一个十年
  4. 《淘宝网开店 SEO 推广 营销 爆款 实战200招》——1.3 网上开店的热门行业有哪些...
  5. [转]鼠标移到图像上显示激活的例子
  6. Redis 常见的性能问题和解决方法
  7. 分布式文件系统FastDFS架构辨析,分布式文件系统FastDFS_V4.06安装部署
  8. 11.4 优化拆分和合并(region)
  9. inline函数的作用
  10. debian6安装后中文乱码