redis 持久化体验

前言

关于Redis的持久化方式共有两种。RDBAOF
可以看先前的文章《redis和memcached 对比》

测试目的

1:测试多种数据结构的操作方式。
2:测试持久化的效果。
3:客户端Java编写(Jedis)。
4:打开密码校验

过程

下载安装Redis

(忽略)

创建Maven工程

在pom.xml中添加如下依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.1</version>
</dependency>

设置密码

打开配置文件。
打开密码设置
搜索requirepass
结果为:

#requirepass foobared 

修改配置

requirepass mypwd

RDB测试

修改RDB的设置
搜索 "save 900 1"
可以看到如下的配置

save 900 1
save 300 10
save 60 10000

save N M 意思就是N秒内执行了M次操作然后执行持久化

添加

save 30 100

30秒内执行了100次操作
在这个配置的下面顺序有很多相关的参数可以配置,这里我们修改一下备份文件的路径

这个是备份的文件名称

dbfilename dump.rdb

修改为

dbfilename mydump.rdb

持久化文件保存的路径,默认是当前路径

dir ./

修改为dumps路径下

dir dumps

编写Java代码

RedisClient代码,

package cn.test.redis;

import java.util.concurrent.locks.ReentrantLock;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Redis连接的对象
 * @author Administrator
 *
 */
public class RedisClient
{
    private JedisPool jedisPool;

    private static RedisClient redisClient;

    /**
     * 保证并发的时候效率最高
     */
    private static ReentrantLock lock=new ReentrantLock();

    private RedisClient()
    {
        initialPool();
    }

    /**
     * 单例
     * @return
     */
    public static RedisClient gi()
    {
        if (redisClient == null)
        {
            lock.lock();
            if (redisClient == null)
            {
                redisClient = new RedisClient();
            }
            lock.unlock();          
        }
        return redisClient;
    }

    /**
     * 获得一个连接
     * @return
     */
    public Jedis getJedis()
    {
        return jedisPool.getResource();
    }

    /**
     * 初始化连接池
     */
    private void initialPool()
    {
        // 池基本配置
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxIdle(5);
        config.setMaxWaitMillis(1000l);
        config.setTestOnBorrow(false);

        //这里设置了超时时间和密码
        jedisPool = new JedisPool(config, "127.0.0.1", 6379,Protocol.DEFAULT_TIMEOUT,"mypwd");
    }

    public void Close()
    {
        jedisPool.close();
    }
}

测试连接是否成功

public class TestPersist
{
    public static void main(String[] args)
    {
         System.out.println(RedisClient.gi().getJedis().ping());
    }
}

运行后显示的内容,表示连接成功。

PONG

完整的测试代码

package cn.test.redis;

import java.util.Map;
import java.util.Map.Entry;

import redis.clients.jedis.Jedis;

public class TestPersist
{
    public static void main(String[] args)
    {
        System.out.println(RedisClient.gi().getJedis().ping());
        saveData();
        //readData();

    }

    static String listName = "myList";
    static String hashName = "myHash";

    /**
     * 先执行数据存储
     */
    public static void saveData()
    {
        int i = 0;
        Jedis jedis = RedisClient.gi().getJedis();
        // string
        for (i = 0; i < 100; i++)
        {
            jedis.set("key" + i, "value" + i);
        }

        // list 添加内容
        for (i = 0; i < 100; i++)
        {
            jedis.lpush(listName, "listValue" + i);
        }
        long length=jedis.llen(listName);
        System.out.println("myList size="+length);

        // 设置hash内容
        for (i = 0; i < 100; i++)
        {
            jedis.hset(hashName, "h_key_" + i, "h_value_" + i);
        }
        length=jedis.hlen(hashName);
        System.out.println("myHash length="+length);
    }

    /**
     * 然后停止服务,重新启动服务,执行读取数据。 当然,需要我们等待60秒
     */
    public static void readData()
    {
        int i = 0;
        Jedis jedis = RedisClient.gi().getJedis();

        // string
        for (i = 0; i < 100; i++)
        {
            System.out.println("----Delete---key-----"+jedis.get("key" + i));
            jedis.del("key" + i);
        }


        /////////////////////////////// list 
        long length=jedis.llen(listName);
        System.out.println("myList size="+length);

        for (i = 0; i < length; i++)
        {
            System.out.println("--Remove-List---"+jedis.lpop(listName));
        }

        /////////////////////////////hash
        length=jedis.hlen(hashName);
        System.out.println("myHash length="+length);
        Map<String,String> hashMap=jedis.hgetAll(hashName);
        String[] keys=new String[(int)length];
        i=0;
        for(Entry<String,String> entry:hashMap.entrySet())
        {
            System.out.println("-----(key="+entry.getKey()+",value="+entry.getValue()+")---");
            keys[i++]=entry.getKey();
        }

        System.out.println("deleNum="+jedis.hdel(hashName, keys));

    }
}

运行后输出的内容

PONG
myList size=100
myHash length=100

观察控制台的输出,当输出类似如下的内容,表示执行了存储,可以查看dumps/mydump.rdb生成了。
[10924] 19 Dec 16:05:28.020 * 100 changes in 30 seconds. Saving…
[10924] 19 Dec 16:05:28.058 * Background saving started by pid 10160
[10924] 19 Dec 16:05:28.259 # fork operation complete
[10924] 19 Dec 16:05:28.261 * Background saving terminated with success

停止redis,然后重新启动。
注释存储,打开读取。
修改代码

//saveData();
readData();

输出如下:

PONG
----Delete---key-----value0
----Delete---key-----value1
----Delete---key-----value2
........
----Delete---key-----value98
----Delete---key-----value99
myList size=100
--Remove-List---listValue99
--Remove-List---listValue98
--Remove-List---listValue97
..........
--Remove-List---listValue3
--Remove-List---listValue2
--Remove-List---listValue1
--Remove-List---listValue0
myHash length=100
-----(key=h_key_0,value=h_value_0)---
-----(key=h_key_1,value=h_value_1)---
-----(key=h_key_2,value=h_value_2)---
.........
-----(key=h_key_10,value=h_value_10)---
-----(key=h_key_98,value=h_value_98)---
-----(key=h_key_11,value=h_value_11)---
-----(key=h_key_99,value=h_value_99)---
deleNum=100

注,Redis默认的持久化的方式就是RDB,而且默认是开启的状态。

测试AOF

修改配置
搜索appendonly

appendonly no

修改为

appendonly yes

表示开启了AOF功能。

搜索appendfsync

appendfsync everysec

默认就是每秒进行同步。

修改Java代码

saveData();
//readData();

执行多次saveData()。
发现aof文件变大了,记住文件大小。
通过reids-cli连接redis。
执行
>BGREWRITEAOF
这时检查aof文件,发现文件大小小了很多。
但是这样手动操作实在是太不科学了,怎么办?
是的,利用crontab来执行计划任务是可以的。。
实际上redis提供了自动的sync的机制。
只要开启了aof功能,自动rewriteaof的功能就开启了,不过他的执行是有一个条件的。

首先需要了解一个数值auto_aofrewrite_base_size
这个值并没有出现在配置文件中,这个值得意思是每次执行BGREWRITEAOF后,redis内部用这个值表示当前的aof文件的大小。知道这个值的意思就好弄了。

接下来看看另外两个参数,这两个参数在配置文件中,可以进行修改。

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

以上是默认值

auto-aof-rewrite-percentage的意思就是当前的aof文件的大小超出auto_aofrewrite_base_size大小的百分比执行rewrite操作。100表示是当前的两倍。
auto-aof-rewrite-min-size的意思就是当前的aof文件必须大于64m的时候才会执行rewrite。

后记

两种持久化方式可以同时使用,可以根据具体场景来选择持久化方案,或者两者同时开启!

参考文章:
http://blog.csdn.net/u011129848/article/details/51527287
http://blog.csdn.net/zyz511919766/article/details/42268219
http://blog.csdn.net/jsjwk/article/details/7971033
http://www.yiibai.com/redis/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值