Redis操作

//为key设置值和过期时间, 设置成功会返回OK, 语法setex key timeout value
setex key1 11 kkk

这里写图片描述

//原来无值设置成功会返回1,原来有值设置失败会返回0
//命令本身设置的键和值是永久的
setnx key2 ttt

这里写图片描述

//搭配expire命令,设置键的超时时间
expire key2 19

这里写图片描述

setnx命令搭配expire命令来实现分布式锁: 首先使用sexnx命令设置键和值,如果返回1表明设置成功,即认为获取到锁,这时再用expire命令设置该键的超时时间,假设有个P1进程获取到锁后执行自己的操作,操作过程中其他进程获取锁一定失败,等P1进程操作完成后主动删除键,这样其他线程又可以竞争锁

hget,hset,hgetall
应用场景:
简单举个实例来描述下Hash的应用场景,比如要存储一个用户信息对象数据,包含以下信息:
用户ID,为查找的key,
存储的value用户对象包含姓名name,年龄age,生日birthday 等信息,
如果用普通的key/value结构来存储,主要有以下2种存储方式:
第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,
如:set u001 “李三,18,20010101”
这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。
第二种方法是这个用户信息对象有多少成员就存成多少个key-value对,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,
如:mset user:001:name “李三” user:001:age 18 user:001:birthday “20010101”
虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常严重的。
Redis提供的Hash很好的解决了这个问题,Redis的Hash实际是内部存储的Value为一个HashMap,
并提供了直接存取这个Map成员的接口,
如:hmset user:001 name “李三” age 18 birthday “20010101”
也就是说,Key仍然是用户ID,value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。
这里同时需要注意,Redis提供了接口(hgetall)可以直接取到全部的属性数据,但是如果内部Map的成员很多,那么涉及到遍历整个内部Map的操作,由于Redis单线程模型的缘故,这个遍历操作可能会比较耗时,而另其它客户端的请求完全不响应,这点需要格外注意。
实现方式:
上面已经说到Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。

set u001 "李三,18,20010101"

这里写图片描述

mset user:001:name "李三" user:001:age 18 user:001:birthday "20010101" 

这里写图片描述

hmset user:001 name "李三" age 18 birthday "20010101"    

这里写图片描述

设置 hash 类型中的属性(字段)值

hset hash_key field_name field_value

返回1,表示 新的属性 field_name <=> field_value 被添加到 hash_key 中;
返回0,表示 旧的属性 field_name 已经存在,且值被更新为 field_value。
这里写图片描述
最后name的值为jack

hsetnx hash_key field_name field_value

返回1,表示 新的属性 field_name <=> field_value 被添加到 hash_key 中;
返回0,表示 属性 field_name 已经存在,不作任何操作
这里写图片描述
最后age的值仍为最初的11

set     设置普通的key value
setex   设置带过期时间的key value
hset    设置hash型(一个): key field value
hmset   设置hash型(多个): key field1 value1 field2 value2
setnx   将key的值设为value,当且仅当key不存在, 存在的话就什么都不做
public static boolean acquireLock(String lock) {
    // 1. 通过SETNX试图获取一个lock
    boolean success = false;
    Jedis jedis = pool.getResource();       
    long value = System.currentTimeMillis() + expired + 1;     
    System.out.println(value);    
    long acquired = jedis.setnx(lock, String.valueOf(value));
    //SETNX成功,则成功获取一个锁
    if (acquired == 1)      
        success = true;
    //SETNX失败,说明锁仍然被其他对象保持,检查其是否已经超时
    else {
        long oldValue = Long.valueOf(jedis.get(lock));
        //超时
        if (oldValue < System.currentTimeMillis()) {
            String getValue = jedis.getSet(lock, String.valueOf(value));               
            // 获取锁成功
            if (Long.valueOf(getValue) == oldValue) 
                success = true;
            // 已被其他进程捷足先登了
            else 
                success = false;
        }
        //未超时,则直接返回失败
        else             
            success = false;
    }        
    pool.returnResource(jedis);
    return success;      
}

这里写图片描述
这里写图片描述

今天在redis中执行set name tom 命令时报了如下错误提示:
(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
大意为:(错误)misconf redis被配置以保存数据库快照,但misconf redis目前不能在硬盘上持久化。用来修改数据集合的命令不能用,请使用日志的错误详细信息。
这是由于强制停止redis快照,不能持久化引起的
解决方案如下:
运行 config set stop-writes-on-bgsave-error no 命令
关闭配置项 解决该问题

常用端口
redis       6379
zookeeper   2181
kafka       9092
MySql       3306
Postgresql  5432
nexus       8081


set     设置普通的key value
setex   设置带过期时间的key value
hset    设置hash型(一个): key field value
hmset   设置hash型(多个): key field1 value1 field2 value2
setnx   将key的值设为value,当且仅当key不存在, 存在的话就什么都不做
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值