Redis3安装配置简单调优Redis集群配置

kevin.Zhu 发布于:2013-2-5 12:35 分类:Redis  有 17 人浏览,获得评论 0 条  

http://www.chinadmd.com/search.do?nkey=redis+3.0+虚拟内存


一、Redis简要介绍

Redis--REmote DIctionary Server,可以直接理解为远程字典服务,也就是基于Key-Value模式Memcached+Database Persistence。

要把Redis与Memcached对比理解:

关于Redis与Memcached的比较更是比比皆是。然而,Redis真的在功能、性能以及内存使用效率上都超越了Memcached吗?

没有必要过多的关心性能,因为二者的性能都已经足够高了。由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。

而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。

说了这么多,结论是,无论你使用哪一个,每秒处理请求的次数都不会成为瓶颈。(比如瓶颈可能会在网卡)

如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。

如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。

当然,最后还得说到你的具体应用需求。Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。

在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。

Redis是什么?两句话可以做下概括:

  • 1.是一个完全开源免费的key-value内存数据库
  • 2.通常被认为是一个数据结构服务器,主要是因为其有着丰富的数据结构 strings、map、 list、sets、 sorted sets

Redis不是什么?同样从两个方面来做下对比:

1.不是sql server、mySQL等关系型数据库,主要原因是:

  • 1)redis目前还只能作为小数据量存储(全部数据能够加载在内存中) ,海量数据存储方面并不是redis所擅长的领域。
  • 2)设计、实现方法很不一样.关系型数据库通过表来存储数据,通过SQL来查询数据。而Redis通上述五种数据结构来存储数据,通过命令 来查询数据。

2. 不是Memcached等缓存系统,主要原因有以下几个:

  • 1、网络IO模型方面:Memcached是多线程,分为监听线程、worker线程,引入锁,带来了性能损耗。Redis使用单线程的IO复用模型,将速度优势发挥到最大,也提供了较简单的计算功能。
  • 2、内存管理方面:Memcached使用预分配的内存池的方式,带来一定程度的空间浪费 并且在内存仍然有很大空间时,新的数据也可能会被剔除,而Redis使用现场申请内存的方式来存储数据,不会剔除任何非临时数据 Redis更适合作为存储而不是cache。
  • 3、数据的一致性方面:Memcached提供了cas命令来保证.而Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。
  • 4、存储方式方面:Memcached只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能。

一句话小结一下:Redis是一个高性能的key-value数据库。redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。

Redis有什么用?只有了解了它有哪些特性

我们在用的时候才能扬长避短,为我们所用:

  • 1.速度快:使用标准C写,所有数据都在内存中完成,读写速度分别达到10万/20万
  • 2.持久化:对数据的更新采用Copy-on-write技术,可以异步地保存到磁盘上,主要有两种策略,一是根据时间,更新次数的快照(save 300 10 )二是基于语句追加方式(Append-only file,aof)
  • 3.自动操作:对不同数据类型的操作都是自动的,很安全
  • 4.快速的主--从复制,官方提供了一个数据,Slave在21秒即完成了对Amazon网站10G key set的复制。
  • 5.Sharding技术: 很容易将数据分布到多个Redis实例中,数据库的扩展是个永恒的话题,在关系型数据库中,主要是以添加硬件、以分区为主要技术形式的纵向扩展解决了很多的应用场景,但随着web2.0、移动互联网、云计算等应用的兴起,这种扩展模式已经不太适合了。

所以近年来,像采用主从配置、数据库复制形式的,Sharding这种技术把负载分布到多个特理节点上去的横向扩展方式用处越来越多。

对Redis数据库做下小结:

  • 1.提高了DB的可扩展性,只需要将新加的数据放到新加的服务器上就可以了
  • 2.提高了DB的可用性,只影响到需要访问的shard服务器上的数据的用户
  • 3.提高了DB的可维护性,对系统的升级和配置可以按shard一个个来搞,对服务产生的影响较小
  • 4.小的数据库存的查询压力小,查询更快,性能更好

Redis与Memcached的比较

  • 1.Memcached是多线程,而Redis使用单线程。
  • 2.Memcached使用预分配的内存池的方式,Redis使用现场申请内存的方式来存储数据,并且可以配置虚拟内存。
  • 3.Redis可以实现持久化,主从复制,实现故障恢复。
  • 4.Memcached只是简单的key与value,但是Redis支持数据类型比较多。

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争。

Redis是个单线程的程序,为什么会这么快呢?

  • 1.大量线程导致的线程切换开销。
  • 2.锁。
  • 3.非必要的内存拷贝。
  • 4.Redis多样的数据结构,每种结构只做自己爱做的事.

Hash对应的Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个HashMap的成员比较少时,Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,当成员量增大时会自动转成真正的HashMap.

Redis小总结:

  • 1.要进行Master-slave配置,出现服务故障时可以支持切换。
  • 2.在master侧禁用数据持久化,只需在slave上配置数据持久化。
  • 3.物理内存+虚拟内存不足,这个时候dump一直死着,时间久了机器挂掉。这个情况就是灾难!
  • 4.当Redis物理内存使用超过内存总容量的3/5时就会开始比较危险了,就开始做swap,内存碎片大
  • 5.当达到最大内存时,会清空带有过期时间的key,即使key未到过期时间。
  • 6.redis与DB同步写的问题,先写DB,后写redis,因为写内存基本上没有问题

使用Memcached,让我感触颇深的是Object Size的问题,由于SQL未作优化直接映射对象,导致缓存对象大于1MB,Memcached就抛了异常。而Redis默认缓存对象512MB,最大支持1GB。

至少在缓存对象时,可以有更大的伸缩空间了! 此外,是数据类型。Memcached比较简单,而Redis可以支持更多复杂的数据类型,如HASH、SET、SortedSet等等。

PS:Memcached是在Server端实现的Sharding,Redis没有对应的实现,据说3.0系列开始支持,不过这话貌似说了2年之久。

二、安装Redis3

Redis装起来,实在是过于简单,让我几乎“无从下手”。因为连“configure”文件都不需要,你只需要做个“make”就好。

在这里下载Redis最新版,这里用Redis 2.4.16

下载并解压Redis:

$ wget http://redis.googlecode.com/files/redis-2.4.16.tar.gz
$ tar zxvf redis-2.4.16.tar.gz

Redis可以解压至任何目录,一个make安装即可获得执行、配置文件,安装(这里将redis解压到/opt/目录下):

cd /opt/redis-2.4.16
make

make之后,我们会得到以下可执行文件:

  • redis-server:Redis服务器的daemon启动程序
  • redis-cli:Redis命令行操作工具。或者通过telnet进行纯文本协议操作
  • redis-benchmark:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能
  • redis-check-aof:用于修复出问题的AOF文件
  • redis-check-dump:用于修复出问题的dump.rdb文件
  • redis-sentinel:用于Redis集群管理

上面几个redis脚本文件位于src目录下。

我习惯性的执行了make install,貌似我需要的可执行文件,安装到了/usr/local/bin目录下。

# make install
cd src && make install

此外,还会得到一个默认的配置文件——redis.conf最好,把它拷贝到固定的目录下,例如:/etc/redis/目录下!

然后,我们就可以在任何路径下,直接启动Redis了!

三、运行尝试启动Redis服务器

运行启动Redis命令也很简单:redis-server /etc/redis/redis.conf

四、简单测试Redis

通过客户端命令redis-cli访问Redis

#redis-cli
redis> set name 51xw
OK
redis> get name
"51xw"

进行benchmark数据测试:redis-benchmark -l,这个测试会一直进行下去,直到你Ctrl+C。

关闭Redis方法也非常简单,通过客户端命令redis-cli完成Redis关闭操作:redis-cli shutdown

六、简单Redis调优方法

修改/etc/sysctl.conf文件:vi /etc/sysctl.conf,在末尾追加vm.overcommit_memory = 1,然后执行sysctl vm.overcommit_memory=1,使之生效。

#sysctl vm.overcommit_memory=1
vm.overcommit_memory = 1

2./proc/sys/vm/overcommit_memory

为了调整内存分配策略,需要配置/proc/sys/vm/overcommit_memory,参数值含义如下:

  • 0,表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
  • 1,表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
  • 2,表示内核允许分配超过所有物理内存和交换空间总和的内存

默认为0,如果内存情况比较紧张的话,设为1:echo 1 > /proc/sys/vm/overcommit_memory

3.修改Redis配置文件redis.conf

前面启动Redis后,总是在命令行里不断跳着各种日志,很麻烦即便通过“&”,领其后台运行,也无济于事。这就需要修改redis.conf,以Daemo模式运行!

redis.conf参数含义如下:

  • daemonize:是否以后台daemon方式运行
  • pidfile:pid文件位置
  • port:监听的端口号
  • timeout:请求超时时间
  • loglevel:log信息级别
  • logfile:log文件位置
  • databases:开启数据库的数量
  • save :保存快照的频率,第一个表示多长时间(秒级),第三个表示执行多少次写操作。在一定时间内执行一定数量的写操作时,自动保存快照。可设置多个条件。
  • rdbcompression:是否使用压缩
  • dbfilename:数据快照文件名(只是文件名,不包括目录)
  • dir:数据快照的保存目录(这个是目录)
  • appendonly:是否开启appendonlylog,开启的话每次写操作会记一条log,这会提高数据抗风险能力,但影响效率。
  • appendfsync:appendonlylog如何同步到磁盘(三个选项,分别是每次写都强制调用fsync、每秒启用一次fsync、不调用fsync等待系统自己同步)
  • slaveof :主从配置,在redis-slave上配置master的ip port,即可。

例如,我们可以修改为如下方式:

daemonize yes #守护进程模式
save 60 1000 #当时间间隔超过60秒,或存储超过1000条记录时,进行持久化。
maxmemory 256mb #分配256MB内存

PS:切记,一定要设定maxmemmory,且配置大小要小于物理内存,留有足够的内存供系统使用。公司一同学的Redis,某期间数据暴涨,导致内存吃紧,SWAP加剧,直接宕机。就是因为没有设置maxmemmory。

七、简单管理Redis集群配置

把鸡蛋都放在一个篮子里是件危险的事情。首先,要做好主备。其次,如果可以做一致性哈希,可以起到负载均衡的作用。

配置Master-Slave,只需要在Slave上配置Master节点IP Port:

这里的Master IP 为192.168.133.139 端口位6379,配置redis.conf: slaveof 192.168.133.139 6379

PS:为了两个Redis Server可以互访,需要注释掉bind 127.0.0.1

依次启动Master,Slave:

Master
[7651] 17 Aug 19:08:07 * Server started, Redis version 2.4.16
[7651] 17 Aug 19:08:07 * DB loaded from disk: 0 seconds
[7651] 17 Aug 19:08:07 * The server is now ready to accept connections on port 6379
[7651] 17 Aug 19:08:08 * Slave ask for synchronization
[7651] 17 Aug 19:08:08 * Starting BGSAVE for SYNC
[7651] 17 Aug 19:08:08 * Background saving started by pid 7652
[7652] 17 Aug 19:08:08 * DB saved on disk
[7651] 17 Aug 19:08:08 * Background saving terminated with success
[7651] 17 Aug 19:08:08 * Synchronization with slave succeeded
Slave
[7572] 17 Aug 19:07:39 * Server started, Redis version 2.4.16
[7572] 17 Aug 19:07:39 * DB loaded from disk: 0 seconds
[7572] 17 Aug 19:07:39 * The server is now ready to accept connections on port 6379
[7572] 17 Aug 19:07:39 * Connecting to MASTER...
[7572] 17 Aug 19:08:08 * MASTER <-> SLAVE sync started: SYNC sent
[7572] 17 Aug 19:08:08 * MASTER <-> SLAVE sync: receiving 10 bytes from master
[7572] 17 Aug 19:08:08 * MASTER <-> SLAVE sync: Loading DB in memory
[7572] 17 Aug 19:08:08 * MASTER <-> SLAVE sync: Finished with success

看到上述日志,就说明Master-Slave已经连通,简单测试,Master写,Slave读:

Redis Master写入测试数据

telnet 192.168.133.139 6379
Trying 192.168.133.139...
Connected to 192.168.133.139.
Escape character is '^]'.
set name snowolf
+OK

Redis Slave读取测试数据

telnet 192.168.133.140 6379
Trying 192.168.133.140...
Connected to 192.168.133.140.
Escape character is '^]'.
get name
$7
snowolf

简单Redis集群体验,搞定!

八、Redis主从备份

在从服务器上执行下列命令:

  • Reids备份redis-cli save
  • 关闭Redis服务器:redis-cli shutdown

然后,拷贝数据目录下的rdb文件。

九、Redis常见的一些系统服务

习惯了通过service启动一切服务,当然,这跟我生产环境部署有关,通常只分配给用于部署的账户操作service命令的权限。主要是为了确保系统安全。

参考之前写的Memcached的系统服务文件,改造一个Redis版本!

新建文件,并赋予权限:

#touch /etc/init.d/redis-server
#chmod +x /etc/init.d/redis-server

编辑/etc/init.d/redis-server,键入如下内容:

#!/bin/bash
# redisStartup script for redis processes
# author: snowolf
# processname: redis
redis_path="/usr/local/bin/redis-server"
redis_conf="/etc/redis/redis.conf"
redis_pid="/var/run/redis.pid"
# Source function library.
./etc/rc.d/init.d/functions
[ -x $redis_path ] || exit 0
RETVAL=0
prog="redis"

# Start daemons.
start() {
    if [ -e $redis_pid -a ! -z $redis_pid ];then
        echo $prog" already running...."
    exit 1
    fi

    echo -n $"Starting $prog "

    # Single instance for all caches
    $redis_path $redis_conf
    RETVAL=$?
    [ $RETVAL -eq 0 ] && {
        touch /var/lock/subsys/$prog
        success $"$prog"
    }
    echo
    return $RETVAL
}

# Stop daemons.
stop() {
    echo -n $"Stopping $prog "
    killproc -d 10 $redis_path
    echo
    [ $RETVAL = 0 ] && rm -f $redis_pid /var/lock/subsys/$prog

    RETVAL=$?
    return $RETVAL
}

# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status $prog
        RETVAL=$?
        ;;
    restart)
        stop
        start
        ;;
    condrestart)
        if test "x`pidof redis`" != x; then
            stop
            start
        fi
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart}"
        exit 1
esac
exit $RETVAL

上面shell脚本用法:

# service redis-server restart
Stopping redis                                             [失败]
Starting redis                                             [确定]
# service redis-server status
redis (pid  14965) 正在运行...

非常方便!