目的:对不同服务器上的redis数据进行同步
1,配置jar包:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sencorsta</groupId> <artifactId>redisTools</artifactId> <version>0.0.1-SNAPSHOT</version> <name>redisTools</name> <dependencies> <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> </dependencies> </project>
2,写配置文件:
redis.properties
# 导出的库 A.redis.pool.maxTotal=512 A.redis.pool.maxIdle=100 A.redis.pool.maxWaitMillis=100000 A.redis.pool.testOnBorrow=true A.redis.pool.testOnReturn=true A.redis.ip=192.168.8.182 A.redis.port=6379 A.redis.expire=1200 A.redis.password= # 导入的库 B.redis.pool.maxTotal=512 B.redis.pool.maxIdle=100 B.redis.pool.maxWaitMillis=100000 B.redis.pool.testOnBorrow=true B.redis.pool.testOnReturn=true B.redis.ip=127.0.0.1 B.redis.port=6379 B.redis.expire=1200 B.redis.password= # 自定义1 ice.redis.pool.maxTotal=512 ice.redis.pool.maxIdle=100 ice.redis.pool.maxWaitMillis=100000 ice.redis.pool.testOnBorrow=true ice.redis.pool.testOnReturn=true ice.redis.ip=127.0.0.1 ice.redis.port=6379 ice.redis.expire=1200 ice.redis.password= # 自定义2 ice2.redis.pool.maxTotal=512 ice2.redis.pool.maxIdle=100 ice2.redis.pool.maxWaitMillis=100000 ice2.redis.pool.testOnBorrow=true ice2.redis.pool.testOnReturn=true ice2.redis.ip=192.168.8.182 ice2.redis.port=6379 ice2.redis.expire=1200 ice2.redis.password=
3,写连接类:
RedisProvider
package redisTools.redis; import java.util.ResourceBundle; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.exceptions.JedisConnectionException; public class RedisProvider { public static Jedis getJedis(String key) { ResourceBundle bundle = ResourceBundle.getBundle("redis"); if (bundle == null) { throw new IllegalArgumentException("[redis.properties] is not found!"); } String typePath = key+".redis."; int expire = Integer.valueOf(bundle.getString(typePath + "expire").trim()); JedisPoolConfig jedisconfigA = new JedisPoolConfig(); jedisconfigA.setMaxTotal(Integer.valueOf(bundle.getString(typePath + "pool.maxTotal").trim())); jedisconfigA.setMaxIdle(Integer.valueOf(bundle.getString(typePath + "pool.maxIdle").trim())); jedisconfigA.setMaxWaitMillis(Long.valueOf(bundle.getString(typePath + "pool.maxWaitMillis").trim())); jedisconfigA.setTestOnBorrow(Boolean.valueOf(bundle.getString(typePath + "pool.testOnBorrow").trim())); jedisconfigA.setTestOnReturn(Boolean.valueOf(bundle.getString(typePath + "pool.testOnReturn").trim())); JedisPool pool=null; if (bundle.getString(typePath + "password") == null || bundle.getString(typePath + "password").trim().equals("")) { pool = new JedisPool(jedisconfigA, bundle.getString(typePath + "ip").trim(), Integer.valueOf(bundle.getString(typePath + "port").trim()), expire); } else { pool = new JedisPool(jedisconfigA, bundle.getString(typePath + "ip").trim(), Integer.valueOf(bundle.getString(typePath + "port").trim()), expire, bundle.getString(typePath + "password").trim()); } Jedis jedis = pool.getResource(); pool.close(); return jedis; } public static void Close(Jedis jedis) { if (jedis != null) { jedis.close(); } } }
4,写数据解析类:
RedisDataUtil
package redisTools.redis; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import java.util.Map; import java.util.Set; import redis.clients.jedis.Jedis; import redis.clients.jedis.Tuple; public class RedisDataUtil { // 备份数据 private static void backups(String path, Object o) throws IOException { File file = new File(path); if (!file.exists()) { file.getParentFile().mkdirs(); file.createNewFile(); } FileOutputStream outStream = new FileOutputStream(file); outStream.write(o.toString().getBytes()); outStream.close(); } /** * 拷贝数据 * * @param redisKeySrc * 源Redis库 * @param redisKeyDes * 目的Redis库 * @param dbIndexSrc * 源DB序号 * @param dbIndexDes * 目的DB序号 */ public static void dataCopyAll(String redisKeySrc, String redisKeyDes, int dbIndexSrc, int dbIndexDes) { System.out.println("开始拷贝:"); Jedis A = null; Jedis B = null; try { A = RedisProvider.getJedis(redisKeySrc); B = RedisProvider.getJedis(redisKeyDes); A.select(dbIndexSrc); B.select(dbIndexDes); Set<String> keys = A.keys("*"); long time = new Date().getTime(); String pathA = "backup/A/db" + dbIndexSrc + "/" + time + "/"; String pathB = "backup/B/db" + dbIndexDes + "/" + time + "/"; int count = 0; int goodCount=0; for (String key : keys) { count++; System.out.println("正在拷贝:" + key + "(" + count + "/" + keys.size() + ")"); String type = A.type(key); if (type.equals("string")) { String value = A.get(key); backups(pathA + key + ".json", value); // 主表数据备份 String copy = B.get(key); if (copy != null) { backups(pathB + key + ".json", value); // 主表数据备份 } B.set(key, value); goodCount++; } else if (type.equals("hash")) { Map<String, String> value = A.hgetAll(key); backups(pathA + key + ".json", value); // 主表数据备份 Map<String, String> copy = B.hgetAll(key); if (copy != null) { backups(pathB + key + ".json", value); // 主表数据备份 } for (Map.Entry<String, String> entry : value.entrySet()) { // 直接把主表的数据覆盖到从表 B.hset(key, entry.getKey(), entry.getValue()); } goodCount++; } else if (type.equals("zset")) { Set<Tuple> value = A.zrangeWithScores(key, 0, -1); backups(pathA + key + ".json", value); // 主表数据备份 Set<Tuple> copy = B.zrangeWithScores(key, 0, -1); if (copy != null) { backups(pathB + key + ".json", value); // 主表数据备份 } for (Tuple entry : value) { // 直接把主表的数据覆盖到从表 B.zadd(key, entry.getScore(), entry.getElement()); } goodCount++; } else { System.out.println("拷贝失败!未知类型:" + type); } } System.out.println("拷贝完成!成功数:"+goodCount+"/"+count); } catch (Exception e) { System.err.println("拷贝出错:" + e.getMessage()); for (StackTraceElement s : e.getStackTrace()) { System.err.println(s.toString()); } } finally { RedisProvider.Close(A); RedisProvider.Close(B); } } }
5调用:
package redisTools; import redisTools.redis.RedisDataUtil; public class CopyTest { public static void main(String[] args) { RedisDataUtil.dataCopyAll("A","B",0,0); RedisDataUtil.dataCopyAll("A","B",1,1); RedisDataUtil.dataCopyAll("A","B",2,2); RedisDataUtil.dataCopyAll("A","B",3,3); } }
输出:
开始拷贝: 正在拷贝:/UUID/(1/4) 正在拷贝:/UID_WX/(2/4) 正在拷贝:/UID_PHONE/(3/4) 正在拷贝:/UID_IMEI/(4/4) 拷贝完成!成功数:4/4 开始拷贝: 正在拷贝:1000025(1/162) 正在拷贝:1000146(2/162) 正在拷贝:1000026(3/162) 正在拷贝:1000147(4/162) 正在拷贝:1000148(5/162) 正在拷贝:1000027(6/162) 正在拷贝:1000149(7/162) 正在拷贝:1000028(8/162) 正在拷贝:1000142(9/162) 正在拷贝:1000021(10/162) 正在拷贝:1000022(11/162) 正在拷贝:1000143(12/162) 正在拷贝:1000144(13/162) 正在拷贝:1000023(14/162) 正在拷贝:1005158(15/162) 正在拷贝:1000024(16/162) 正在拷贝:1000145(17/162) 正在拷贝:1000029(18/162) 正在拷贝:1000140(19/162) 正在拷贝:1000020(20/162) 正在拷贝:1000141(21/162) 正在拷贝:1005152(22/162) 正在拷贝:1000135(23/162) 正在拷贝:1000014(24/162) 正在拷贝:1000136(25/162) 正在拷贝:1000015(26/162) 正在拷贝:1000016(27/162) 正在拷贝:1000137(28/162) 正在拷贝:1000138(29/162) 正在拷贝:1000017(30/162) 正在拷贝:1000098(31/162) 正在拷贝:1000010(32/162) 正在拷贝:1000131(33/162) 正在拷贝:1000132(34/162) 正在拷贝:1000099(35/162) 正在拷贝:1000011(36/162) 正在拷贝:1000012(37/162) 正在拷贝:1000133(38/162) 正在拷贝:1000134(39/162) 正在拷贝:1000013(40/162) 正在拷贝:1007963(41/162) 正在拷贝:1007446(42/162) 正在拷贝:1000139(43/162) 正在拷贝:1000018(44/162) 正在拷贝:1000019(45/162) 正在拷贝:1008379(46/162) 正在拷贝:1100265(47/162) 正在拷贝:1000094(48/162) 正在拷贝:1000095(49/162) 正在拷贝:1000096(50/162) 正在拷贝:1000097(51/162) 正在拷贝:1000130(52/162) 正在拷贝:1000090(53/162) 正在拷贝:1000091(54/162) 正在拷贝:1000092(55/162) 正在拷贝:1000093(56/162) 正在拷贝:1000047(57/162) 正在拷贝:1006947(58/162) 正在拷贝:1006946(59/162) 正在拷贝:1000048(60/162) 正在拷贝:1000049(61/162) 正在拷贝:1000043(62/162) 正在拷贝:1000044(63/162) 正在拷贝:1000045(64/162) 正在拷贝:1000046(65/162) 正在拷贝:1008444(66/162) 正在拷贝:1008600(67/162) 正在拷贝:1100012(68/162) 正在拷贝:1000040(69/162) 正在拷贝:1000041(70/162) 正在拷贝:1000042(71/162) 正在拷贝:1000036(72/162) 正在拷贝:1000157(73/162) 正在拷贝:1000037(74/162) 正在拷贝:1000038(75/162) 正在拷贝:1000039(76/162) 正在拷贝:1006933(77/162) 正在拷贝:1000153(78/162) 正在拷贝:1000035(79/162) 正在拷贝:1008839(80/162) 正在拷贝:1007862(81/162) 正在拷贝:1000150(82/162) 正在拷贝:1000030(83/162) 正在拷贝:1000151(84/162) 正在拷贝:1000152(85/162) 正在拷贝:1000031(86/162) 正在拷贝:1000102(87/162) 正在拷贝:1000103(88/162) 正在拷贝:1000104(89/162) 正在拷贝:1000105(90/162) 正在拷贝:1000065(91/162) 正在拷贝:1000066(92/162) 正在拷贝:1000067(93/162) 正在拷贝:1000100(94/162) 正在拷贝:1004389(95/162) 正在拷贝:1000068(96/162) 正在拷贝:1000101(97/162) 正在拷贝:1008902(98/162) 正在拷贝:1000106(99/162) 正在拷贝:1000107(100/162) 正在拷贝:1000108(101/162) 正在拷贝:1000109(102/162) 正在拷贝:1007098(103/162) 正在拷贝:1100239(104/162) 正在拷贝:1000061(105/162) 正在拷贝:1000062(106/162) 正在拷贝:1000063(107/162) 正在拷贝:1000064(108/162) 正在拷贝:1000060(109/162) 正在拷贝:1000058(110/162) 正在拷贝:1000730(111/162) 正在拷贝:1000059(112/162) 正在拷贝:1000056(113/162) 正在拷贝:1000057(114/162) 正在拷贝:1000050(115/162) 正在拷贝:1006950(116/162) 正在拷贝:1005189(117/162) 正在拷贝:1100068(118/162) 正在拷贝:1000003(119/162) 正在拷贝:1000124(120/162) 正在拷贝:1006869(121/162) 正在拷贝:1000004(122/162) 正在拷贝:1000125(123/162) 正在拷贝:1000005(124/162) 正在拷贝:1000126(125/162) 正在拷贝:1000127(126/162) 正在拷贝:1000006(127/162) 正在拷贝:1000120(128/162) 正在拷贝:1000087(129/162) 正在拷贝:1000121(130/162) 正在拷贝:1000088(131/162) 正在拷贝:1000001(132/162) 正在拷贝:1000122(133/162) 正在拷贝:1000089(134/162) 正在拷贝:1000002(135/162) 正在拷贝:1000123(136/162) 正在拷贝:1007317(137/162) 正在拷贝:1000007(138/162) 正在拷贝:1000128(139/162) 正在拷贝:1000129(140/162) 正在拷贝:1000008(141/162) 正在拷贝:1000009(142/162) 正在拷贝:1007155(143/162) 正在拷贝:1000083(144/162) 正在拷贝:1000084(145/162) 正在拷贝:1100179(146/162) 正在拷贝:1000085(147/162) 正在拷贝:1000086(148/162) 正在拷贝:1000080(149/162) 正在拷贝:1000081(150/162) 正在拷贝:1000082(151/162) 正在拷贝:1000113(152/162) 正在拷贝:1000114(153/162) 正在拷贝:1000116(154/162) 正在拷贝:1000110(155/162) 正在拷贝:1000111(156/162) 正在拷贝:1000112(157/162) 正在拷贝:1000117(158/162) 正在拷贝:1000118(159/162) 正在拷贝:1000119(160/162) 正在拷贝:1008352(161/162) 正在拷贝:1008597(162/162) 拷贝完成!成功数:162/162 开始拷贝: 正在拷贝:Notice_List(1/24) 正在拷贝:/CODE/list(2/24) 正在拷贝:bankTransfer(3/24) 正在拷贝:hhzl_all(4/24) 正在拷贝:/GLOBAL/ingotrank(5/24) 正在拷贝:com.fengjin.entity.laohuji(6/24) 正在拷贝:/CODE/used(7/24) 正在拷贝:daily_sign(8/24) 正在拷贝:/GLOBAL/online(9/24) 正在拷贝:com.fengjin.entity.shisanshui(10/24) 正在拷贝:com.fengjin.entity.user_system(11/24) 正在拷贝:com.fengjin.entity.cfg(12/24) 正在拷贝:/GLOBAL/orders(13/24) 正在拷贝:transrecord(14/24) 正在拷贝:signgiftcfg(15/24) 正在拷贝:/GLOBAL/nickname(16/24) 正在拷贝:identification(17/24) 正在拷贝:task(18/24) 正在拷贝:init_money(19/24) 正在拷贝:/CODE/new(20/24) 正在拷贝:loginInfo(21/24) 正在拷贝:appinfo(22/24) 正在拷贝:com.fengjin.entity.xiaomali(23/24) 正在拷贝:/GLOBAL/rank(24/24) 拷贝完成!成功数:24/24 开始拷贝: 正在拷贝:R5L15_JP1(1/31) 正在拷贝:HLCZ_JP(2/31) 正在拷贝:R5L15_JP2(3/31) 正在拷贝:R5L15_JP3(4/31) 正在拷贝:brnn_win(5/31) 正在拷贝:wjl_win_history(6/31) 正在拷贝:hjzy_win(7/31) 正在拷贝:wjl_win(8/31) 正在拷贝:wjl_cfg(9/31) 正在拷贝:brnn_cfg(10/31) 正在拷贝:hhzl_win(11/31) 正在拷贝:XIAOMALI.JP.FREE(12/31) 正在拷贝:XIAOMALI.JP(13/31) 正在拷贝:dsy_win(14/31) 正在拷贝:SSS.TIPS(15/31) 正在拷贝:SSS.WIN(16/31) 正在拷贝:dsy_lvl(17/31) 正在拷贝:HLCZ_FREE_JP(18/31) 正在拷贝:dsy_jp1(19/31) 正在拷贝:brnn_win_history(20/31) 正在拷贝:dsy_jp2(21/31) 正在拷贝:hlcz_win(22/31) 正在拷贝:hjzy_lvl(23/31) 正在拷贝:XIAOMALI.WIN(24/31) 正在拷贝:dsy_jp3(25/31) 正在拷贝:R5L15_FREE_JP1(26/31) 正在拷贝:R5L15_FREE_JP2(27/31) 正在拷贝:R5L15_FREE_JP3(28/31) 正在拷贝:dsy_free_jp1(29/31) 正在拷贝:dsy_free_jp2(30/31) 正在拷贝:dsy_free_jp3(31/31) 拷贝完成!成功数:31/31