分布式锁(string)

setnx key value,当key不存在时,将 key 的值设为 value ,返回1。若给定的 key 已经存在,则setnx不做任何动作,返回0。

当setnx返回1时,表示获取锁,做完操作以后del key,表示释放锁,如果setnx返回0表示获取锁失败。设置过期时期,当遇到宕机时,会在过期后释放锁。

计数器(string)

如知乎每个问题的被浏览器次数

set key 0

incr key // incr readcount::{帖子id} 每阅读一次

get key // get readcount::{帖子id} 获取阅读量

分布式全局唯一id(string)

分布式全局唯一id的实现方式有很多,这里只介绍用redis实现

每次获取userId的时候,对userId加1再获取,可以改进为如下形式

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190110202218333.jpg

直接获取一段userId的最大值,缓存到本地慢慢累加,快到了userId的最大值时,再去获取一段,一个用户服务宕机了,也顶多一小段userId没有用到

incr :自增1

incrby:自增一小段

set userId 0

incr usrId //返回1

incrby userId 1000 //返回10001

消息队列(list)

在list里面一边进,一边出即可

#实现方式一

#一直往list左边放

lpush key value

#key这个list有元素时,直接弹出,没有元素被阻塞,直到等待超时或发现可弹出元素为止,上面例子超时时间为10s

brpop key value 10

#实现方式二

#一直往list右边放

rpush key value

blpop key value 10

新浪/Twitter用户消息列表(list)

假如说小编li关注了2个微博a和b,a发了一条微博(编号为100)就执行如下命令

lpush msg::li 100

b发了一条微博(编号为200)就执行如下命令:

lpush msg::li 200

假如想拿最近的10条消息就可以执行如下命令(最新的消息一定在list的最左边):

# 下标从0开始,[start,stop]是闭区间,都包含

lrange msg::li 0 9

抽奖活动(set)

#参加抽奖活动

sadd key {userId}

#获取所有抽奖用户,大轮盘转起来

smembers key

#抽取count名中奖者,并从抽奖活动中移除

spop key count

#抽取count名中奖者,不从抽奖活动中移除

srandmember key count

实现点赞,签到,like等功能(set)

# 1001用户给8001帖子点赞

sadd like::8001 1001

# 取消点赞

srem like::8001 1001

# 检查用户是否点过赞

sismember like::8001 1001

# 获取点赞的用户列表

smembers like::8001

# 获取点赞用户数

scard like::8001

实现关注模型,可能认识的人(set)

seven关注的人

sevenSub -> {qing, mic, james}

青山关注的人

qingSub->{seven,jack,mic,james}

Mic关注的人

MicSub->{seven,james,qing,jack,tom}

#返回sevenSub和qingSub的交集,即seven和青山的共同关注

sinter sevenSub qingSub -> {mic,james}

#我关注的人也关注他,下面例子中我是seven

#qing在micSub中返回1,否则返回0

sismember micSub qing

sismember jamesSub qing

#我可能认识的人,下面例子中我是seven

#求qingSub和sevenSub的差集,并存在sevenMayKnow集合中

sdiffstore sevenMayKnow qingSub sevenSub -> {seven,jack}

电商商品筛选(set)

每个商品入库的时候即会建立他的静态标签列表如,品牌,尺寸,处理器,内存

# 将拯救者y700P-001和ThinkPad-T480这两个元素放到集合brand::lenovo

sadd brand::lenovo 拯救者y700P-001 ThinkPad-T480

sadd screenSize::15.6 拯救者y700P-001 机械革命Z2AIR

sadd processor::i7 拯救者y700P-001 机械革命X8TIPlus

# 获取品牌为联想,屏幕尺寸为15.6,并且处理器为i7的电脑品牌(sinter为获取集合的交集)

sinter brand::lenovo screenSize::15.6 processor::i7 -> 拯救者y700P-001

排行版(zset)

redis的zset天生是用来做排行榜的、好友列表, 去重, 历史记录等业务需求

#user1的用户分数为 10

zadd ranking 10 user1

zadd ranking 20 user2

#取分数最高的3个用户

zrevrange ranking 0 2 withscores

发布,订阅消息(消息通知)

比如你关注了迪丽热巴,迪丽热巴发微博你就会收到推送

引用: https://www.cnblogs.com/xinde123/p/8489054.html

redis的发布与订阅(发布/订阅)是它的一种消息通信模式,一方发送信息,一方接收信息。

下图是三个客户端同时订阅同一个频道

下图是有新信息发送给频道1时,就会将消息发送给订阅它的三个客户端

java实现 redis的发布订阅

回顾java如何操作redis:

redis是一种缓存数据库,它也是C/S的结构,也就是客户端和服务端,一般来说,在java中,我们通常使用

jedis(客户端)去操作redis(服务端),这其中操作的时候,两者之间肯定要建立连接,就像数据库链接一样,在关系型数据库中,我们一般都维护一个连接池,以达到链接的复用,来省去建立连接和关闭连接的时间。所以在jedis中,同样也存在一个jedispool(jedis连接池)的概念,我们都是从池中去取连接使用。

引入jedis依赖

redis.clients

jedis

2.8.0

建立一个Publisher (发布者)

package pubsub;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPool;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

/**

* Created by Yuk on 2019/1/10.

*/

public class Publisher extends Thread{

private final JedisPool jedisPool;

public Publisher(JedisPool jedisPool) {

this.jedisPool = jedisPool;

}

@Override

public void run() {

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

Jedis jedis = jedisPool.getResource(); //连接池中取出一个连接

while (true) {

String line = null;

try {

line = reader.readLine();

if (!"quit".equals(line)) {

jedis.publish("mychannel", line); //从 mychannel 的频道上推送消息

} else {

break;

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

再建立一个订阅者

package pubsub;

import redis.clients.jedis.JedisPubSub;

/**

* Created by Yuk on 2019/1/10.

*/

public class Subscriber extends JedisPubSub{

public Subscriber(){}

@Override

public void onMessage(String channel, String message){ //收到消息会调用

System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));

}

@Override

public void onSubscribe(String channel, int subscribedChannels){ //订阅了频道会调用

System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",

channel, subscribedChannels));

}

@Override

public void onUnsubscribe(String channel, int subscribedChannels){ //取消订阅 会调用

System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",

channel, subscribedChannels));

}

}

这里订阅者需要继承JedisPubSub,来重写它的三个方法。用途 注释上已经写了,很简单。

我们这里只是定义了一个订阅者,下面去订阅频道。

package pubsub;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPool;

/**

* Created by Yuk on 2019/1/10.

*/

public class SubThread extends Thread{

private final JedisPool jedisPool;

private final Subscriber subscriber = new Subscriber();

private final String channel = "mychannel";

public SubThread(JedisPool jedisPool) {

super("SubThread");

this.jedisPool = jedisPool;

}

@Override

public void run() {

System.out.println(String.format("subscribe redis, channel %s, thread will be blocked", channel));

Jedis jedis = null;

try {

jedis = jedisPool.getResource(); //取出一个连接

jedis.subscribe(subscriber, channel); //通过subscribe 的api去订阅,入参是订阅者和频道名

} catch (Exception e) {

System.out.println(String.format("subsrcibe channel error, %s", e));

} finally {

if (jedis != null) {

jedis.close();

}

}

}

}

最后,再写一个测试类去跑一下。键盘输入消息,订阅者就会触发onMessage方法

package pubsub;

import redis.clients.jedis.JedisPool;

import redis.clients.jedis.JedisPoolConfig;

/**

* Created by Yuk on 2019/1/10.

*/

public class PubSubDemo{

public static void main( String[] args ){

// 连接redis服务端

JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "127.0.0.1", 6379);

System.out.println(String.format("redis pool is starting, redis ip %s, redis port %d", "127.0.0.1", 6379));

SubThread subThread = new SubThread(jedisPool); //订阅者

subThread.start();

Publisher publisher = new Publisher(jedisPool); //发布者

publisher.start();

}

}

java的redis的作用_redis用途相关推荐

  1. java利用redis实现排行榜_Redis实现排行榜

    ZSet有序集合 redis的有序集合与集合一样也是String类型元素的集合,不允许有重复的元素. 每一个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的 ...

  2. java token redis生成算法_Redis实现单点登录

    Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久 ...

  3. 【redis】java操作redis时,StringRedisTemplate的expire()方法的作用,什么时候使用

    java操作redis时,StringRedisTemplate的expire()方法的作用,什么时候使用 //重新设置过期时间为30分钟,刷新时间 redisTemplate.expire(MsOp ...

  4. java 标识符用途_java标识符是什么?java标识符有什么作用?

    学习java的过程中,很多含义大家还是要知道的,这样才能更好的学习java,最近有小伙伴想知道java标识符是什么?那么接下来,我们就来给大家讲解一下这方面的内容. 就是程序员在定义java程序时,自 ...

  5. 2021-3-20 狂神说java之 redis学习

    Nosql概述 Nosql = not only sql (不仅仅是SQL) 泛指非关系型数据库 关系型数据库:表格,行,列 很多的数据类型用户的个人信息,社交网络,地理位置.这些数据类型的存储不需要 ...

  6. redis setnx 原子性_Redis从入门到深入-分布式锁(26)

    1. 分布式锁 1.1 简介 锁 是一种用来解决多个执行线程 访问共享资源 错误或数据不一致问题的工具 如果 把一台服务器比作一个房子,那么 线程就好比里面的住户,当他们想要共同访问一个共享资源,例如 ...

  7. Java连接Redis及操作(一)

    Redis简介 Redis是一个开源的使用ANSI c语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.它是一种非关系性的数据库.它是以key-val ...

  8. Redis 笔记之 Java 操作 Redis(Jedis)

    Java 操作 Redis 环境准备 引入依赖 创建 jedis 对象 操作 Key 相关 API 操作 String 相关 API 操作 List 相关 API 操作 Set 的相关 API 操作 ...

  9. redis set 超时_redis分布式锁3种实现方式对比分析总结

    我在这篇文章提到了分布式锁,但没有展开来讲,抛砖引玉,今天就来说说高并发服务编程中的redis分布式锁. 这里罗列出3种redis实现的分布式锁,并分别对比说明各自特点. Redis单实例分布式锁 实 ...

最新文章

  1. 独家 | 如何手动优化神经网络模型(附链接)
  2. ExecutorService线程池
  3. 自学python什么时候能够兼职-总结下我是如何利用python在闲余时间月赚5千外快...
  4. 实现BFS之“营救”
  5. 机器学习知识点(二十一)特征选择之岭回归和LASSO
  6. 使用 Async 和 Await 的异步编程
  7. txt mining 2(tf-idf)
  8. 信息学奥赛一本通 1128:图像模糊处理 | OpenJudge NOI 1.8 13:图像模糊处理
  9. 自动/持续部署Docker 的tomcat web项目(二)
  10. 畅通工程再续 最小生成树
  11. Java开发中的基本数据类型有哪些?
  12. Linux系统管理01--系统命令精讲
  13. Entity Framework 实践系列 —— 搞好关系 - 两情相悦(双向一对一)
  14. Rdlc报表出现空白页解决方法
  15. 去除移动端alert/confirm的网址(url)
  16. php值班系统,php简单的值日值班处理方法
  17. cocos creator切换场景闪退_#Cocos Creator# 为什么音乐音效在场景切换的时候自动停止了?...
  18. 高通 qca-wifi 移植
  19. HTTP 协议之Gzip压缩原理
  20. Web前端:React Native Web与React — 比较指南

热门文章

  1. 微信公众号开发之-回调的所有类型
  2. SIEMENS PLC Web API 学习记录
  3. latex编译的pdf书签中不能显示公式
  4. QGIS中使用Python快速建立多个矢量数据
  5. 玩转KOL,小程序社交信用电商小优店完成A轮千万美元融资
  6. YouTube数据库如何保存巨量视频文件?
  7. #金专奖获奖方案展播# | 移动端云机魔测平台
  8. 从印度、非洲到欧洲,华为、阿里巴巴们一路向西的扩张运动
  9. Java线程--同步和异步的区别
  10. 【转】[译] zram.txt