JobPlus知识库 IT DBA 文章
Java实现Redis持久化到数据库的关键方法

项目中有些使用的redis存储,当对redis进行rehash的时候感觉是比较麻烦的。于是写了个简单的读取redis到数据库的关键方法。

[java] 

  1. package com.redis.web;  
  2.   
  3. import java.util.Date;  
  4. import java.util.Iterator;  
  5. import java.util.Set;  
  6.   
  7. import redis.clients.jedis.Jedis;  
  8.   
  9. import com.redis.entity.RedisTable;  
  10.   
  11. public class RedisPersistence {  
  12.     /** 
  13.      * 存储所有的redis对象方法 
  14.      */  
  15.     public static void saveAllRedis(final String redisIp,final int redisPort,final String appCode) {  
  16.         Jedis redis = new Jedis(redisIp, redisPort);// 连接redis  
  17.         // redis.auth("redis");//验证密码  
  18.         // KEY操作  
  19.         Set keys = redis.keys("*");// 列出所有的key,查找特定的key如:redis.keys("foo")  
  20.         Iterator t1 = keys.iterator();  
  21.         while (t1.hasNext()) {  
  22.             Object obj1 = t1.next();  
  23.             saveRedisObject(redis, obj1 + "", redisIp, redisPort + "", appCode);  
  24.         }  
  25.     }  
  26.       
  27.     /** 
  28.      * 存储单个对象 
  29.      * @param redis 
  30.      * @param redisKey 
  31.      * @param macIp 
  32.      * @param port 
  33.      * @param appCode 
  34.      */  
  35.     private static void saveRedisObject(final Jedis  redis,final String redisKey,final String macIp,final String port,final String appCode) {  
  36.         String redisType = redis.type(redisKey);  
  37.         RedisTable redisTable = new RedisTable();  
  38.         redisTable.setAppCode(appCode);  
  39.         redisTable.setCreateTime(new Date());  
  40.         redisTable.setMacIp(macIp);  
  41.         redisTable.setPort(port);  
  42.         redisTable.setRedisKey(redisKey);  
  43.         redisTable.setRedisType(redisType);  
  44.         redisTable.setRemark("");  
  45.         redisTable.setUpdateTime(new Date());  
  46.         //set集合  
  47.         if("set".equalsIgnoreCase(redisType)){  
  48.             Set<String> setStrings  = redis.smembers(redisKey);//获取key的所有set集合  
  49.             if(null != setStrings && !setStrings.isEmpty()){  
  50.                 Iterator setIterator = setStrings.iterator() ;     
  51.                    while(setIterator.hasNext()){     
  52.                        Object obj1 = setIterator.next();    
  53.                        redisTable.setRedisValue(obj1+"");  
  54.                        printRedis(redisTable);//保存每一个set记录  
  55.                    }    
  56.             }  
  57.         //hash集合  
  58.         }else if("hash".equalsIgnoreCase(redisType)){  
  59.             Set<String> hashSets = redis.hkeys(redisKey);  
  60.             if(null != hashSets && !hashSets.isEmpty()){  
  61.                 Iterator setIterator = hashSets.iterator() ;     
  62.                    while(setIterator.hasNext()){     
  63.                        String objectName = setIterator.next()+"";    
  64.                        redisTable.setObjectName(objectName);  
  65.                        redisTable.setRedisValue(redis.hget(redisKey, objectName));  
  66.                        printRedis(redisTable);//保存每一个set记录  
  67.                    }    
  68.             }  
  69.         //list集合  
  70.         }else if("list".equalsIgnoreCase(redisType)){  
  71.             Long listLen = redis.llen(redisKey);  
  72.             for (Long i = 0L; i < listLen; i++) {  
  73.                 redisTable.setRedisValue(redis.lindex(redisKey, i));  
  74.                 printRedis(redisTable);  
  75.             }  
  76.         //sortedset集合  
  77.         }else if("sortedset".equalsIgnoreCase(redisType)){  
  78. //          Long redisLenth = redis.zcard(redisKey);  
  79.             Set<String> sortedsets = redis.zrange(redisKey, 0, -1);  
  80.             if(null != sortedsets && !sortedsets.isEmpty()){  
  81.                 Iterator setIterator = sortedsets.iterator() ;     
  82.                    while(setIterator.hasNext()){     
  83.                        String sortedMember = setIterator.next() +"";    
  84.                        redisTable.setRedisValue(sortedMember);  
  85.                        redisTable.setScore("" +redis.zscore(redisKey, sortedMember));  
  86.                        printRedis(redisTable);//保存每一个sortedset记录  
  87.                    }    
  88.             }  
  89.         //string集合  
  90.         }else if("string".equalsIgnoreCase(redisType)){  
  91.             redisTable.setRedisValue(redis.get(redisKey));  
  92.             printRedis(redisTable);//保存记录  
  93.         }else{  
  94.             System.out.println("UnknowRedisType-----redisType: " +redisType+"      objValue: "+redis.get(redisKey));  
  95.         }  
  96.     }  
  97.   
  98.     //打印输出  
  99.     public static void printRedis (RedisTable redisTable) {  
  100.         System.out.println("redisType:"+redisTable.getRedisType()    
  101.                         + " redisKey:"+redisTable.getRedisKey()  
  102.                         + " ObjectName:"+redisTable.getObjectName()  
  103.                         + " redisValue:"+redisTable.getRedisValue()  
  104.                         + " redisScore:"+redisTable.getScore()  
  105.         );  
  106.     }  
  107.       
  108.     public static void main(String[] args) {  
  109.         String redisIp = "127.0.0.1";//redis的IP地址  
  110.         int redisPort = 6379;//redis的端口号  
  111.         String appCode = "FUYOU";//根据不同的应用区分的appcode  
  112.         saveAllRedis(redisIp,redisPort,appCode);  
  113.     }  
  114. }  


其中的appCode是不需要的,这里只是为了针对于不同的应用,可以使用同一个redis进行持久化备份而已(通过appcode来区分)。

其中使用的RedisTable实例如下:


[java] 

  1. package com.redis.entity;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class RedisTable {  
  6.     private Long redisId; //保存redis的主键ID  
  7.     private String redisType;//redis的类型如:set/list/hash/sortedset/string  
  8.     private String redisKey;//保存redis时使用的key  
  9.     private String objectName;//此属性主要用于hash数据结构时,保存member的  
  10.     private String redisValue;//存储的redis的值  
  11.     private String keyToken;//保存Token时,为区分拼接的字符串  
  12.     private String score;//此属性为sortedset数据结构时,保存的score值  
  13.     private Date createTime;//创建时间  
  14.     private Date updateTime;//更新时间  
  15.     private String macIp;//redis的IP地址  当然此处也可以存储mac地址  
  16.     private String port;//redis使用的端口号  
  17.     private String appCode;//应用区分码  
  18.     private String remark;//备注  
  19.     private String isModify;//是否修改。此属性可以用于增量备份时,即在每个redis存储时可以更具key多存储一个属性isModify。 如果有修改,则置为 Y,否则为N.  
  20.       
  21. ///////////////////////此处省略 setter  and getter 方法////////////////////////  
  22.   
  23.   
  24. }  

以上方法可以扩充用于redis备份中心。

在使用redis增量备份时,请根据rediskey在数据块中查找是否存在。根据更新值返回的0或者是1,进行更新或者新增的操作。

当然数据库的表结构目前只是一张表,如果数据量很大的情况下,可以将端口、IP、appCode信息存储到单独的一张表,减少数据冗余。

以上的时间复杂度以及效率上并没有优化。如果要求比较高,请自行优化。


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
498人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序