百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Redis入门篇-五种基本数据类型及使用场景

mhr18 2024-11-14 16:17 23 浏览 0 评论

前期准备工作(如无需要可直接跳过)

  • redis安装

具体的安装教程可参考之前的章节(https://www.jianshu.com/p/91f90adb782f)

  • 启动redis server(如果没有redis install,可在src目录下找到启动命令)

执行bin/redis-server命令,出现如下图就说明启动成功

bin/redis-server命令后面可以指定redis的配置文件(配置文件中配置了一些参数),具体的配置文件可关注博主,后期会不断更新,共同进步;

  • 启动redis client(如果没有redis install,可在src目录下找到启动命令)

执行bin/redis-cli [-h ip] [-p port],出现如下图所示说明客户端启动并连接成功


执行
ping命令,测试是否连接成功,出现如下图所示表示连接成功

redis的五种类型

  • string:字符串类型
  • list:列表
  • hash:hash,类似于Java中的hashMap数据结构

有序,顺序为插入的顺序

允许重复值

  • set:无序去重列表,与Java中的set类似

无序

对值进行去重

  • zset(sorted set):有序去重列表

结构体中有score的值,会根据这个score的值进行排序

对值进行去重

string

  • 部分基本命令

命令

解释说明

语法

实例

set

给一个key设置string的值

set key value

set k1 v1

mset

set的批量操作

mset key value [key value ...]

mset k1 v1 k2 v2

setex

set增强,添加过期时间

setex key seconds value

setex k1 10 v1

setnx

只有当key不存在的时候才会设置值

setnx key value

setnx k1 v1

setrange

重置指定位置的字符

setrange key offset value

setrange k1 1 v2

get

获取指定key的string值

get key

get k1

append

追加string值到一个key的末尾

append key value

append k1 v2

mget

get的批量操作

mget key [key ...]

mget k1 k2 k3

incr

对int类型的值+1操作

incr key

incr k1

incrby

对int类型的值+整数操作

incrbykey increment

incrby k1 10

incrbyfloat

对int类型的值+浮点数操作

incrbyfloat key increment

incrbyfloat k1 0.5

decr

对int类型的值-1操作

decr key

decr k1

decrby

对int类型的值-整数操作

decrby key decrement

decrby k1 10

decrbyfloat

对int类型的值-浮点数操作

decrbyfloat key decrement

decrbyfloat k1 0.5

提示:可使用help @string查看所有string的相关命令以使用语法与含义;

  • 应用场景

1、分布式锁的实现(简易版jedis)

public class SimpleDistributedLock {
    // treadcount
    private static final int threadCount = 100;
    private static CountDownLatch countDownLatch = new CountDownLatch(threadCount);
    // 1000个库存
    private static int inv = 1;
    // 锁的key
    private static final String lockKey = "distributedLock:simple";
    // 锁超时时间
    private static final long expireSeconds = 10;
    // redisson
    private static RedissonClient redissonClient;
    // redis host
    private static final String redisHost = "127.0.0.1";
    // redis port
    private static final int redisPort = 6379;
    // 初始化连接redis
    static {
        Config config = new Config();
        config.useSingleServer().setAddress(redisHost + ":" + redisPort);
        redissonClient = Redisson.create(config);
    }
    public static void main(String[] args) throws InterruptedException {
        // 模拟并发 扣减库存
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                RLock lock = redissonClient.getLock(lockKey);
                try {
                    // 设置过期时间 并 加锁(获取锁)
                    lock.lock(expireSeconds, TimeUnit.SECONDS);
                    // 业务 扣减库存
                    if (inv > 0) {
                        inv--;
                    }

                } catch (Exception e) {
                    // 回滚业务操作
                } finally {
                    lock.unlock();
                    countDownLatch.countDown();
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println(inv);
        redissonClient.shutdown();
    }
}

2、分布式计数器

public class Counter {
    private static int count = 0;
    // treadcount
    private static final int threadCount = 100;
    private static CountDownLatch countDownLatch = new CountDownLatch(threadCount);
    // 锁的key
    private static final String lockKey = "distributedLock:simple";
    // 锁超时时间
    private static final long expireSeconds = 10;
    // redisson
    private static RedissonClient redissonClient;
    // redis host
    private static final String redisHost = "127.0.0.1";
    // redis port
    private static final int redisPort = 6379;
    // 初始化连接redis
    static {
        Config config = new Config();
        config.useSingleServer().setAddress(redisHost + ":" + redisPort);
        redissonClient = Redisson.create(config);
    }
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                RLock lock = redissonClient.getLock(lockKey);
                try {
                    lock.lock(expireSeconds, TimeUnit.SECONDS);
                    // 业务操作
                    count++;
                } finally {
                    countDownLatch.countDown();
                    lock.unlock();
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println(count);
        redissonClient.shutdown();
    }
}

3、统计用户一年内的登录情况

# uid为key,每一位代表着一年中的一天
# 2016123240用户在第一天登录过
127.0.0.1:6379> SETBIT uid_2016123240 0 1
(integer) 0
# 2016123240用户在第八天登录过
127.0.0.1:6379> SETBIT uid_2016123240 7 1
(integer) 0
# 2016123240用户在第二十二天登录过
127.0.0.1:6379> SETBIT uid_2016123240 21 1
(integer) 0
# 2016123240用户在第三十一天登录过
127.0.0.1:6379> SETBIT uid_2016123240 30 1
(integer) 0
# 2016123240用户在第五十六天登录过
127.0.0.1:6379> SETBIT uid_2016123240 55 1
(integer) 0
# 2016123240用户在第三百六十六天登录过
127.0.0.1:6379> SETBIT uid_2016123240 365 1
(integer) 0
# 获取2016123240用户在这一年内的登录次数
127.0.0.1:6379> BITCOUNT uid_2016123240 0 -1
(integer) 6

4、统计近7天登录过的用户数

127.0.0.1:6379> SETBIT 20210628 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210628 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210628 3 1
(integer) 0
127.0.0.1:6379> SETBIT 20210628 4 1
(integer) 0
127.0.0.1:6379> SETBIT 20210629 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210629 6 1
(integer) 0
127.0.0.1:6379> SETBIT 20210629 5 1
(integer) 0
127.0.0.1:6379> SETBIT 20210629 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210630 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210630 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210630 9 1
(integer) 0
127.0.0.1:6379> SETBIT 20210630 5 1
(integer) 0
127.0.0.1:6379> SETBIT 20210701 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210701 6 1
(integer) 0
127.0.0.1:6379> SETBIT 20210701 3 1
(integer) 0
127.0.0.1:6379> SETBIT 20210701 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210702 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210702 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210702 10 1
(integer) 0
127.0.0.1:6379> SETBIT 20210703 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210703 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210703 6 1
(integer) 0
127.0.0.1:6379> SETBIT 20210704 1 1
(integer) 0
127.0.0.1:6379> BITOP or orResult 20210628 20210629 20210630 20210701 20210702 20210703 20210704
(integer) 2
127.0.0.1:6379> BITCOUNT orResult 0 -1
(integer) 8

5、统计最近7天连续登录的用户数

127.0.0.1:6379> SETBIT 20210628 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210628 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210628 3 1
(integer) 0
127.0.0.1:6379> SETBIT 20210628 4 1
(integer) 0
127.0.0.1:6379> SETBIT 20210629 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210629 6 1
(integer) 0
127.0.0.1:6379> SETBIT 20210629 5 1
(integer) 0
127.0.0.1:6379> SETBIT 20210629 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210630 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210630 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210630 9 1
(integer) 0
127.0.0.1:6379> SETBIT 20210630 5 1
(integer) 0
127.0.0.1:6379> SETBIT 20210701 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210701 6 1
(integer) 0
127.0.0.1:6379> SETBIT 20210701 3 1
(integer) 0
127.0.0.1:6379> SETBIT 20210701 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210702 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210702 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210702 10 1
(integer) 0
127.0.0.1:6379> SETBIT 20210703 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20210703 2 1
(integer) 0
127.0.0.1:6379> SETBIT 20210703 6 1
(integer) 0
127.0.0.1:6379> SETBIT 20210704 1 1
(integer) 0
127.0.0.1:6379> BITOP and andResult 20210628 20210629 20210630 20210701 20210702 20210703 20210704
(integer) 2
127.0.0.1:6379> BITCOUNT andResult 0 -1
(integer) 1

list

  • 部分基本命令

命令

解释说明

语法

实例

lpush

添加一个或者多个值到list中

lpush key value [value ...]

lpush k1 v1 v2

lpop

移除且获取列表中第一个元素

lpop key

lpop k1

llen

获取列表长度

llen key

llen k1

lindex

获取列表中指定index的值

lindex key index

lindex k1 0

linsert

向列表中指定元素前/后插入元素

linsert key before/after pivot value

linsert k1 after v1

lrange

从列表中获取范围的值

lrange key start stop

lrange k1 0 -1

lpushx

如果list存在,则添加一个值到list中

lpushx key value

lpushx k1 v1

lrem

从列表中删除指定个数的指定元素

lrem key count value

lrem k1 2 v1

lset

将列表中指定index的值设置为value

lset key index value

lset k1 1 v1

ltrim

将列表截取指定范围

ltrim key start stop

ltrim k1 1 2

rpush

添加一个或者多个值到list最后中

rpush key value [value ...]

rpush k1 v1 v2

rpop

移除且获取列表中最后一个元素

rpop key

rpop k1

rpushx

如果list存在,则添加一个值到list最后

rpushx key value

rpushx k1 v1

rpoplpush

移除一个列表中的最后一个元素,并将这个元素添加到另一个列表的第一个元素并返回

rpoplpush source destination

rpoplpush k1 k2

blpop

移除且获取第一个元素(阻塞直到元素存在)

BLPOP key [key ...] timeout

blpop k1 10

brpop

移除且获取最后一个元素(阻塞直到元素存在)

BRPOP key [key ...] timeout

brpop k1 10

brpoplpush

移除一个列表中的最后一个元素,并将这个元素添加到另一个列表的第一个元素并返回(阻塞直到元素存在)

brpoplpush source destination timeout

brpoplpush k1 k2 10

  • 应用场景

1、消息队列:主要是通过blpush+brpop实现;

2、常用数据结构实现

3、lpush + rpop 实现队列;

4、lpush + lpop 实现栈;

hash

  • 部分基本命令

命令

解释说明

语法

实例

hget

获取hash的属性的值

hget key field

hget k1 name

hgetall

获取所有的hash的属性和值

hgetall key

hgetall k1

hmget

批量获取hash的属性的值

hmget key field [field ...]

hmget k1 name age

hset

设置hash的指定属性的值

hset key field value

hset k1 name n1

hsetnx

如果不存在,则设置hash的指定属性的值

hsetnx key field value

hsetnx k1 name n1

hmset

批量设置hash的指定属性的值

hmset key field value [field value ...]

hmset k1 name n1 age 18

hdel

删除指定key的属性

hdel key field [field ...]

hdel k1 name age

hkeys

获取key的所有的属性

hkeys key

hkeys k1

hvals

获取key的所有属性的值

hvals key

hvals k1

hstrlen

获取指定key的指定属性的值的长度

hstrlen key field

hstrlen k1 name

hlen

获取指定key的属性个数

hlen key

hlen k1

hincrby

指定key的指定属性值增加整数值

hincrby key field increment

hincrby k1 age 5

hincrbyfloat

指定key的指定属性值增加浮点值

hincrbyfloat key field increment

hincrbyfloat k1 age 5.5

hexists

判断是否存在某一个属性

hexists key field

hexists k1 name

  • 应用场景

1、存储对象(object):set user name zhangsan age 13

2、购物车:

添加到购物车:hset shop_car product_1001 1

增加商品个数:hincrby shop_car product_1001 2

删除商品:hdel shop_car product_1001

计算购物车商品种类数:hlen shop_car

set

  • 部分基本命令

命令

解释说明

语法

实例

sadd

添加一个或多个元素

sadd key member [member ...]

sadd k1 v1 v2 v3

scard

获取set的元素个数

scard key

scard k1

sdiff

差集

sdiff key [key ...]

sdiff k1 k2

sdiffstore

计算差集并将结果存储在另一个key

sdiffstore destination key [key ...]

sdiffstore result k1 k2

sinter

交集

sinter key [key ...]

sinter k1 k2

sinterstore

计算交集并将结果存储在另一个key

sinterstore destination key [key ...]

sinterstore result k1 k2

sismember

判断是否存在值

sismember key member

sismember k1 v1

smembers

获取set的所有值

smember key

smember k1

smove

移动set的指定值到另一个set中

smove source destination member

smove k1 target v1

spop

移除并返回指定个数的数

spop key [count]

spop k1 2

srandmember

获取指定范围的一个或多个值

srandmember key [count]

srandmember k1 2

srem

删除指定值

srem key member [member ...]

srem k1 v1

sscan

迭代

sscan key cursor [MATCH pattern] [COUNT count]

``

sunion

并集

sunion key [key ...]

sunion k1 k2

sunionstore

计算并集并将结果存储到新的set中

sunionstore destination key [key ...]

sunionstore result k1 k2

  • 应用场景

1、微博关注/粉丝列表:sadd follow 1 2 3/ sadd fans 1 2 3

2、共同关注列表:sinter follow1 follow2

3、猜你喜欢:sdiff follow1 follow2

4、随机抽奖:spop award_pool 10

zset

  • 部分基本命令

命令

解释说明

语法

实例

zadd

添加一个或多个元素(带有score)

zadd key score member [score member ...]

zadd k1 1 v1 2 v2

zcard

获取set的元素个数

zcard key

zcard k1

zcount

计算value在min-max中的个数

zcount key min max

zcount k1 1 10

zincrby

指定值增加指定整数值

zincrby key increment member

zincrby k1 10 v1

zinterstore

交集并将结果存储到另一个zset

zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM]

zinterstore result k1 k2

zlexcount

计算zset中score在min-max的值得个数

zlexcount key min max

zlexcount k1 1 10

zpopmax 弹出并返回count个最高分的元素


zpopmax key [count]

zpopmax k1 2

zpopmin 弹出并返回count个最低分的元素


zpopmin key [count]

zpopmin k1 2

zrangebyscore

获取根据分数获取指定范围内的值

zrangebyscore key min max [WITHSCORES] [LIMIT offset count]

zrangebyscore k1 1 10

zrank

获取指定元素的index

zrank key member

zrank k1 v1

zscan

迭代

zscan key cursor [MATCH pattern] [COUNT count]

``

zscore

获取指定值的score

zscore key member

zscore k1 v1

zunionstore

计算并集并将结果存储到另一个zset

zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM]

zset result k1 k2

zrem

删除一个或多个元素

zrem key member [member ...]

zrem k1 v1 v2 v3

  • 应用场景

1、微博热搜

2、最新列表

应用场景实战,后续待更新,如果您觉得有帮助,麻烦点个三连,给个关注。

相关推荐

一文读懂Prometheus架构监控(prometheus监控哪些指标)

介绍Prometheus是一个系统监控和警报工具包。它是用Go编写的,由Soundcloud构建,并于2016年作为继Kubernetes之后的第二个托管项目加入云原生计算基金会(C...

Spring Boot 3.x 新特性详解:从基础到高级实战

1.SpringBoot3.x简介与核心特性1.1SpringBoot3.x新特性概览SpringBoot3.x是建立在SpringFramework6.0基础上的重大版...

「技术分享」猪八戒基于Quartz分布式调度平台实践

点击原文:【技术分享】猪八戒基于Quartz分布式调度平台实践点击关注“八戒技术团队”,阅读更多技术干货1.背景介绍1.1业务场景调度任务是我们日常开发中非常经典的一个场景,我们时常会需要用到一些不...

14. 常用框架与工具(使用的框架)

本章深入解析Go生态中的核心开发框架与工具链,结合性能调优与工程化实践,提供高效开发方案。14.1Web框架(Gin,Echo)14.1.1Gin高性能实践//中间件链优化router:=...

SpringBoot整合MyBatis-Plus:从入门到精通

一、MyBatis-Plus基础介绍1.1MyBatis-Plus核心概念MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提...

Seata源码—5.全局事务的创建与返回处理

大纲1.Seata开启分布式事务的流程总结2.Seata生成全局事务ID的雪花算法源码3.生成xid以及对全局事务会话进行持久化的源码4.全局事务会话数据持久化的实现源码5.SeataServer创...

Java开发200+个学习知识路线-史上最全(框架篇)

1.Spring框架深入SpringIOC容器:BeanFactory与ApplicationContextBean生命周期:实例化、属性填充、初始化、销毁依赖注入方式:构造器注入、Setter注...

OpenResty 入门指南:从基础到动态路由实战

一、引言1.1OpenResty简介OpenResty是一款基于Nginx的高性能Web平台,通过集成Lua脚本和丰富的模块,将Nginx从静态反向代理转变为可动态编程的应用平台...

你还在为 Spring Boot3 分布式锁实现发愁?一文教你轻松搞定!

作为互联网大厂后端开发人员,在项目开发过程中,你有没有遇到过这样的问题:多个服务实例同时访问共享资源,导致数据不一致、业务逻辑混乱?没错,这就是分布式环境下常见的并发问题,而分布式锁就是解决这类问题的...

近2万字详解JAVA NIO2文件操作,过瘾

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。从classpath中读取过文件的人,都知道需要写一些读取流的方法,很是繁琐。最近使用IDEA在打出.这个符号的时候,一行代...

学习MVC之租房网站(十二)-缓存和静态页面

在上一篇<学习MVC之租房网站(十一)-定时任务和云存储>学习了Quartz的使用、发邮件,并将通过UEditor上传的图片保存到云存储。在项目的最后,再学习优化网站性能的一些技术:缓存和...

Linux系统下运行c++程序(linux怎么运行c++文件)

引言为什么要在Linux下写程序?需要更多关于Linux下c++开发的资料请后台私信【架构】获取分享资料包括:C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdf...

2022正确的java学习顺序(文末送java福利)

对于刚学习java的人来说,可能最大的问题是不知道学习方向,每天学了什么第二天就忘了,而课堂的讲解也是很片面的。今天我结合我的学习路线为大家讲解下最基础的学习路线,真心希望能帮到迷茫的小伙伴。(有很多...

一个 3 年 Java 程序员 5 家大厂的面试总结(已拿Offer)

前言15年毕业到现在也近三年了,最近面试了阿里集团(菜鸟网络,蚂蚁金服),网易,滴滴,点我达,最终收到点我达,网易offer,蚂蚁金服二面挂掉,菜鸟网络一个月了还在流程中...最终有幸去了网易。但是要...

多商户商城系统开发全流程解析(多商户商城源码免费下载)

在数字化商业浪潮中,多商户商城系统成为众多企业拓展电商业务的关键选择。这类系统允许众多商家在同一平台销售商品,不仅丰富了商品种类,还为消费者带来更多样的购物体验。不过,开发一个多商户商城系统是个复杂的...

取消回复欢迎 发表评论: