因为项目有两个服务器,一个开发服务器,一个测试服务器,也就需要着需要两套redis服务。所以需要导出数据再导入到另外一个redis中。在网上搜索了一下。
redis的备份和还原,借助了第三方的工具,redis-dump
1、安装redis-dump
代码如下:
[root@localhost tank]# yum install ruby rubygems ruby-devel //安装rubygems 以及相关包
[root@localhost tank]# gem sources -a //源,加入淘宝,外面的源不能访问
added to sources
[root@localhost tank]# gem install redis-dump -V //安装redis-dump
2、redis-dump导出数据
代码如下:
[root@localhost tank]# telnet 127.0.0.1 6379 //telnet到redis
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set test 11 //设置一个值
+OK
get test //取值
$2
11
[root@localhost tank]# redis-dump -u 127.0.0.1:6379 >test.json //导出数据
3、redis-load还原数据
代码如下:
[root@localhost tank]# telnet 127.0.0.1 6379 //telnet到redis
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
flushall //请空所有数据
+OK
keys * //查看已清空
*0
[root@localhost tank]# < test.json redis-load //导入数据
[root@localhost tank]# telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
keys * //已导入成功
*1
$4
test
但是没有成功,懒得折腾这个玩意了,就自己写了个java代码,先凑合着用吧。首先写两个util类,用来连接两个redis,因为是从线上服务器拷贝数据到测试数据库,所以为了简单就拷贝了两套。
public class RedisUtil {
public static JedisPool jedisPool = null;
// Redis服务器IP
private static String ADDR = "";
// Redis的端口号
private static int PORT = 6379;
// 访问密码
private static String AUTH = "";
/**
* 初始化Redis连接池
*/
static {
try {
JedisPoolConfig config = new JedisPoolConfig();
// 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
config.setBlockWhenExhausted(true);
// 设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)
config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
// 是否启用pool的jmx管理功能, 默认true
config.setJmxEnabled(true);
// 最大空闲连接数, 默认8个 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
config.setMaxIdle(8);
// 最大连接数, 默认8个
config.setMaxTotal(200);
// 表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
config.setMaxWaitMillis(1000 * 100);
// 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
config.setTestOnBorrow(true);
jedisPool = new JedisPool(config, ADDR, PORT, 3000,AUTH);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取Jedis实例
*
* @return
*/
public synchronized static Jedis getJedis() {
try {
if (jedisPool != null) {
Jedis resource = jedisPool.getResource();
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 释放jedis资源
*
* @param jedis
*/
public static void close(final Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
public static void main(String[] args) {
System.out.println(getJedis());
}
}
还有一个叫做CopyRedisUtil.java里面内容都一样,除了端口号和密码不同之外。
接下来就是我们的数据迁移类
public class RedisTransfer {
private static JedisPool jedisPool;
private static Jedis jedis;
private static JedisPool copyJedisPool;
private static Jedis copyJedis;
static {
jedisPool = RedisUtil.jedisPool;
jedis = RedisUtil.getJedis();
;
copyJedisPool = CopyRedisUtil.jedisPool;
copyJedis = CopyRedisUtil.getJedis();
}
/**
*
* @Title: get @Description: TODO(获取数据) @param: @param
* key @param: @return @return: String @throws
*/
public static String get(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return jedis.get(key);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (null != jedis)
jedis.close();
}
return null;
}
/**
*
* @Title: hget @Description: TODO(查询数据) @param: @param key @param: @param
* field @param: @return @return: String @throws
*/
public static String hget(String key, String field) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return jedis.hget(key, field);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (null != jedis)
jedis.close();
}
return null;
}
/**
*
* @Title: hset @Description: TODO(设置从表数据) @param: @param key @param: @param
* field @param: @param value @param: @return @return: Long @throws
*/
public static Long copyHset(String key, String field, String value) {
Jedis jedis = null;
try {
jedis = copyJedisPool.getResource();
return jedis.hset(key, field, value);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (null != jedis)
jedis.close();
}
return null;
}
/**
*
* @Title: backups
* @Description: TODO(数据备份)
* @param: @param file
* @param: @param o
* @return: void
* @throws
*/
public static void backups(String file, Object o) {
try {
FileOutputStream outStream = new FileOutputStream(file);
outStream.write(o.toString().getBytes());
outStream.close();
System.out.println("successful");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* @Title: dataTransfer @Description: TODO(数据迁移) @param:表名 @return:
* void @throws
*/
public static void dataTransfer(String tableName) {
Map<String, String> json = jedis.hgetAll(tableName); // 根据表名得到主表所有的数据
backups("c:///"+tableName+".txt", json); //主表数据备份
Map<String, String> copyJson = copyJedis.hgetAll(tableName); // 根据表名得到从表所有的数据
backups("c:///Copy"+tableName+".txt", json); //从表数据备份
copyJedis.del(tableName); //删除从表的数据
for (Map.Entry<String, String> entry : json.entrySet()) { // 直接把主表的数据覆盖到从表
copyHset(tableName, entry.getKey(), entry.getValue());
}
}
public static void main(String[] args) {
dataTransfer("account");
}
}
我把数据备份在C盘;
不想折腾redis-dump的可以下载我的代码看看,非常简单实用,特地拿出来分享一番。