项目中有些使用的redis存储,当对redis进行rehash的时候感觉是比较麻烦的。于是写了个简单的读取redis到数据库的关键方法。仅供参考。
package com.redis.web; import java.util.Date; import java.util.Iterator; import java.util.Set; import redis.clients.jedis.Jedis; import com.redis.entity.RedisTable; public class RedisPersistence { /** * 存储所有的redis对象方法 */ public static void saveAllRedis(final String redisIp,final int redisPort,final String appCode) { Jedis redis = new Jedis(redisIp, redisPort);// 连接redis // redis.auth("redis");//验证密码 // KEY操作 Set keys = redis.keys("*");// 列出所有的key,查找特定的key如:redis.keys("foo") Iterator t1 = keys.iterator(); while (t1.hasNext()) { Object obj1 = t1.next(); saveRedisObject(redis, obj1 + "", redisIp, redisPort + "", appCode); } } /** * 存储单个对象 * @param redis * @param redisKey * @param macIp * @param port * @param appCode */ private static void saveRedisObject(final Jedis redis,final String redisKey,final String macIp,final String port,final String appCode) { String redisType = redis.type(redisKey); RedisTable redisTable = new RedisTable(); redisTable.setAppCode(appCode); redisTable.setCreateTime(new Date()); redisTable.setMacIp(macIp); redisTable.setPort(port); redisTable.setRedisKey(redisKey); redisTable.setRedisType(redisType); redisTable.setRemark(""); redisTable.setUpdateTime(new Date()); //set集合 if("set".equalsIgnoreCase(redisType)){ Set<String> setStrings = redis.smembers(redisKey);//获取key的所有set集合 if(null != setStrings && !setStrings.isEmpty()){ Iterator setIterator = setStrings.iterator() ; while(setIterator.hasNext()){ Object obj1 = setIterator.next(); redisTable.setRedisValue(obj1+""); printRedis(redisTable);//保存每一个set记录 } } //hash集合 }else if("hash".equalsIgnoreCase(redisType)){ Set<String> hashSets = redis.hkeys(redisKey); if(null != hashSets && !hashSets.isEmpty()){ Iterator setIterator = hashSets.iterator() ; while(setIterator.hasNext()){ String objectName = setIterator.next()+""; redisTable.setObjectName(objectName); redisTable.setRedisValue(redis.hget(redisKey, objectName)); printRedis(redisTable);//保存每一个set记录 } } //list集合 }else if("list".equalsIgnoreCase(redisType)){ Long listLen = redis.llen(redisKey); for (Long i = 0L; i < listLen; i++) { redisTable.setRedisValue(redis.lindex(redisKey, i)); printRedis(redisTable); } //sortedset集合 }else if("sortedset".equalsIgnoreCase(redisType)){ // Long redisLenth = redis.zcard(redisKey); Set<String> sortedsets = redis.zrange(redisKey, 0, -1); if(null != sortedsets && !sortedsets.isEmpty()){ Iterator setIterator = sortedsets.iterator() ; while(setIterator.hasNext()){ String sortedMember = setIterator.next() +""; redisTable.setRedisValue(sortedMember); redisTable.setScore("" +redis.zscore(redisKey, sortedMember)); printRedis(redisTable);//保存每一个sortedset记录 } } //string集合 }else if("string".equalsIgnoreCase(redisType)){ redisTable.setRedisValue(redis.get(redisKey)); printRedis(redisTable);//保存记录 }else{ System.out.println("UnknowRedisType-----redisType: " +redisType+" objValue: "+redis.get(redisKey)); } } //打印输出 public static void printRedis (RedisTable redisTable) { System.out.println("redisType:"+redisTable.getRedisType() + " redisKey:"+redisTable.getRedisKey() + " ObjectName:"+redisTable.getObjectName() + " redisValue:"+redisTable.getRedisValue() + " redisScore:"+redisTable.getScore() ); } public static void main(String[] args) { String redisIp = "127.0.0.1";//redis的IP地址 int redisPort = 6379;//redis的端口号 String appCode = "FUYOU";//根据不同的应用区分的appcode saveAllRedis(redisIp,redisPort,appCode); } }
其中使用的RedisTable实例如下:
package com.redis.entity; import java.util.Date; public class RedisTable { private Long redisId; //保存redis的主键ID private String redisType;//redis的类型如:set/list/hash/sortedset/string private String redisKey;//保存redis时使用的key private String objectName;//此属性主要用于hash数据结构时,保存member的 private String redisValue;//存储的redis的值 private String keyToken;//保存Token时,为区分拼接的字符串 private String score;//此属性为sortedset数据结构时,保存的score值 private Date createTime;//创建时间 private Date updateTime;//更新时间 private String macIp;//redis的IP地址 当然此处也可以存储mac地址 private String port;//redis使用的端口号 private String appCode;//应用区分码 private String remark;//备注 private String isModify;//是否修改。此属性可以用于增量备份时,即在每个redis存储时可以更具key多存储一个属性isModify。 如果有修改,则置为 Y,否则为N. ///////////////////////此处省略 setter and getter 方法//////////////////////// }
在使用redis增量备份时,请根据rediskey在数据块中查找是否存在。根据更新值返回的0或者是1,进行更新或者新增的操作。
当然数据库的表结构目前只是一张表,如果数据量很大的情况下,可以将端口、IP、appCode信息存储到单独的一张表,减少数据冗余。
以上的时间复杂度以及效率上并没有优化。如果要求比较高,请自行优化。
希望各位大侠给出建议,共同进步!