项目中有些使用的redis存储,当对redis进行rehash的时候感觉是比较麻烦的。于是写了个简单的读取redis到数据库的关键方法。
[java]
- 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);
- }
- }
其中的appCode是不需要的,这里只是为了针对于不同的应用,可以使用同一个redis进行持久化备份而已(通过appcode来区分)。
其中使用的RedisTable实例如下:
[java]
- 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备份中心。
在使用redis增量备份时,请根据rediskey在数据块中查找是否存在。根据更新值返回的0或者是1,进行更新或者新增的操作。
当然数据库的表结构目前只是一张表,如果数据量很大的情况下,可以将端口、IP、appCode信息存储到单独的一张表,减少数据冗余。
以上的时间复杂度以及效率上并没有优化。如果要求比较高,请自行优化。
登录 | 立即注册