Redis 应用(篇一 数据类型讲解)

Redis 相关应用

题主为一个工作5年的java 开发,项目中有不少地方有应用到redis, 但使用都较为简单,零碎,今天就来将这些零碎的redis 使用归纳一下,不正之处,还请诸君不吝指正,话不多说,上正文。

Redis 数据类型(String)

redis 有(String(字符串),Hash(哈希),List(列表),Set(集合),zset(sorted set:有序集合) ) 5种数据类型,题主所作项目中,应用到的也就string这种类型,原来有存list 的需求,个人有在list 里边踩过坑,这个相信很多朋友可能都会和我踩一样的坑,这个后文会提到。

相信绝大多数的传统公司一个redis 的string 类型都可以满足其需求了,常用的方法也就(get/set/del)方法了,稍微大型的传统公司可能还有个setNx 应用(这个会在redis 锁这一篇会有详解),get/set/del  无非就是增删改查,但是在这里有种简单的方式来绕过上文踩到的坑, 关于存储List 到Redis, 这边题主是使用Gson, 调用 GSON.toJson(roleList); 方法将其转换成字符串存储。那问题来了,在一个List 很大的情况下,该不该存放reids 呢?或者Gson 做转换 效率又是多少呢?在大并发的场景下这些方法会不会存在问题呢?

问题 一   redis 官网已经给出了答案(单个key 存储的最大值为512M)

问题二 那关于要不要将这么大的k v 放在redis 呢?

我们都知道java 中HashMap 也是K V结构 ,众所周知map 在寻找一个Key 的时候 是类似我们数据库的索引一样直接找到的,不会存在去循环遍历这个key 的情况(这点有疑问的可以去翻我的博客,关于map 那一章会有描述)。那我们的redis 是不是也是这种结构呢?这点还请同仁们自行解答。

问题三  在并发场景下Gson 的序列化是否会成为redis 的性能瓶颈呢?

 这点就参考其他博主的测试结果  在200000个UserDto 由Object=>Json 做10次测试 结果单位为毫秒 博主链接 如下:

Gson、Fastjson和Jackson速度对比_sanding的博客-CSDN博客_jackson和fastjson

问题三 关于redis 所说的对象存储呢?

1. 以jedis 为例调用set 方法存放byte[] ,将对象转换成序列化为 byte[]

2. 使用Gson.toJson()方法按字符串来存储

Hash(哈希)

这种类型其实在传统公司中不常见,实际上hash 就是K V 中的V 以Map 的形式存储。

    /**
     * hash 存储
     * @param key
     * @param hash
     * @return
     */
    public String hmSet(byte[] key, Map<byte[], byte[]> hash) {
        String res;
        Jedis jedis = getRecource();
        try {
            res = jedis.hmset(key, hash);
        } finally {
            jedis.close();
        }
        return res;
    }


    /**
     * java 序列化方法
     *
     * @return
     */
    public static byte[] serializable(Object o) {
        byte[] bytes = null;
        ByteArrayOutputStream  outArray = new ByteArrayOutputStream();
        ObjectOutputStream out;
        try {
            out = new ObjectOutputStream(outArray);
            out.writeObject(o);
            out.flush();
            out.close();
            outArray.close();
            bytes = outArray.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

如下是测试代码

    @Test
    public void testHmset() {
        String key = "user1";
        Map<byte[], byte[]> map = new HashMap<>();
        map.put("name".getBytes(), "zs".getBytes());
        Integer age = 15;

        map.put("age".getBytes(), JedisUtils.serializable(age));
        String res = jedisUtils.hmSet(key.getBytes(), map);
        System.out.println("res: " + res);
    }

由此可见,hash 存储可以存对象,但是在取数的时候需要自己写反序列化方法,将hash 序列化成Object。

在腾讯课堂上看到在hash 的应用场景其中在hash 的优势说是比String 更节省空间,但使用jedis 存储对象有说法是 将对象转换成byte[]

会更为占用空间,两种说法限于题主水平有限,无法分别那种是对的。

在集群环境中hash 使用上会有key 的数据倾斜,redis 是根据key 来做路由,当单个的key 所存储的V 比较大时这个K V 只会存储在集群的某一节点中,造成数据倾斜较大(但实际String 也会有这种问题呀?知道的大佬能否解答一下)

Hash 和 String  存储对象的区别

1. 相较于string 来说,hash 存储 也有hmset 批量存一个对象,其结构类似于K,V  但是 v 里边 嵌套一个k v,结构类似于Map<String,Map<object,object>>, 其在取的过程中便于做查询,可以取某一个v,而无需整个对象拿出来做序列化。下面代码是对redis hash 的存取操作,可以看到hash 类型做查询是比较方便的。无需将整个对象拿出来做序列化。

    @Test
    public void testSetRedisHash(){
        Map<String,String> value = new HashMap<>();
        value.put("name","zs");
        value.put("sex","N");
        String res = redisUtil.hmSet("user", value);
        System.out.println("res"+res);
    }

    @Test
    public void testGetRedisHash(){
        String res = redisUtil.hGet("user", "name");
        System.out.println(res);
    }

List 结构

Set 结构

Zset 结构

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值