本系列文章,笔者准备对互联网缓存利器Redis的使用,做一下简单的总结,内容大概如下:
博文内容 | 资源链接 |
---|---|
Linux环境下搭建Redis基础运行环境 | https://blog.csdn.net/smilehappiness/article/details/107298145 |
互联网缓存利器-Redis的使用详解(基础篇) | https://blog.csdn.net/smilehappiness/article/details/107592368 |
Redis基础命令使用Api详解 | https://blog.csdn.net/smilehappiness/article/details/107593218 |
Redis编程客户端Jedis、Lettuce和Redisson的基础使用 |
https://blog.csdn.net/smilehappiness/article/details/107301988 |
互联网缓存利器-Redis的使用详解(进阶篇) | https://blog.csdn.net/smilehappiness/article/details/107592336 |
如何基于Redis实现分布式锁 | https://blog.csdn.net/smilehappiness/article/details/107592896 |
基于Redis的主从复制、哨兵模式以及集群的使用,史上最详细的教程来啦~ | https://blog.csdn.net/smilehappiness/article/details/107433525 |
Redis相关的面试题总结 | https://blog.csdn.net/smilehappiness/article/details/107592686 |
Redis作为互联网的缓存利器之一,那么,如何使用Redis客户端进行编程呢?上一篇中,介绍了Linux环境下搭建Redis基础运行环境,接下来,将带你了解下Redis编程客户端Jedis
、Lettuce
和Redisson
的基础使用。
当下流行的Redis客户端也就是这三种,也是官网推荐使用的,后续有其他好用的客户端的话再进行更新。
官网文档: http://redisdoc.com/
redis-cli
(Redis Command Line Interface)是Redis自带的基于命令行的Redis客户端,用于与服务端交互,我们可以使用该客户端来执行redis的各种命令。
连接本地redis服务
如果是连接本地的redis服务,可以启动./redis-cli
,直接连接redis(默认ip127.0.0.1,端口6379)
指定ip和端口号连接redis服务
使用命令: ./redis-cli -h 127.0.0.1 -p 6379
如果redis服务设置了密码,需要使用auth命令认证才可以正常使用
auth password
也可以直接一步到位:./redis-cli -h 127.0.0.1 -p 6379 -a password
切换库命令
redis默认为16个库,redis默认自动使用0号库,切换库使用以下命令:
select db-index
如:
测试redis运行是否正常
ping
,返回PONG
,说明redis服务运行正常
添加key以及对应的value(字符串类型)
set key1 v1
获取key对应的value(字符串类型)
get key1
将一个或多个值 value 插入到列表 key 的表头(列表类型)
语法:LPUSH key value [value …]
lpush list1 1,2,3
将一个或多个值 value 插入到列表 key 的表尾(最右边)(列表类型)
语法:RPUSH key value [value …]
rpush list1 3
返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定(列表类型)
语法: LRANGE key start stop
下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
lrange list1 0 5
查看当前数据库中key的数目
dbsize
删除当前库的数据
flushdb
删除所有库的数据
flushall
查看redis服务器的统计信息
info
获得redis的所有配置项(redis.conf配置信息)
config get *
redis的数据类型有九种,常用的有5种,这里不再一一举例,感兴趣的童鞋们,可以按照官网示例,进行练习。
Jedis
是一个很小巧,但功能很健全的redis的java客户端。Jedis Client其实就是一个jar包,放到项目中,利用该jar包连接和操作redis。
Jedis api操作相对来说比较简单,一个redis命令对应一个jedis方法,只要熟悉redis的api,那也就相当于掌握了Jedis的api操作。
Jedis源码地址:https://github.com/xetorthio/jedis
Jedis api文档: http://xetorthio.github.io/jedis/
【代码示例】
package cn.smilehappiness.client.jedis;
import redis.clients.jedis.Jedis;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* <p>
* 使用Jedis Client操作redis基础使用
* jedis api操作相对来说比较简单,一个redis命令对应一个jedis方法
* <p/>
*
* @author smilehappiness
* @Date 2020/7/12 18:42
*/
public class JedisClient {
private static Jedis jedis;
static {
//根据ip和端口连接redis
jedis = new Jedis("127.0.0.1", 6379);
//如果redis服务端设置了访问密码
jedis.auth("123456789");
//检测redis服务是否访问正常
if ("PONG".equals(jedis.ping())) {
System.out.println("redis服务运行成功!");
}
}
public static void main(String[] args) throws InterruptedException {
/**********字符串(strings)类型的相关操作**********/
redisByString();
/**********列表(lists)类型的相关操作**********/
/**********集合(sets)类型的相关操作**********/
/**********有序集合(sorted sets)(zset)类型的相关操作**********/
/**********哈希表-哈希(hashes)类型的相关操作**********/
//关闭与redis的连接
jedis.close();
}
private static void redisByString() throws InterruptedException {
// set命令(将字符串值 value 关联到 key,如果 key 已经持有其他值, SET 就覆写旧值, 无视类型)
jedis.set("k1", "v1");
// get命令
String v1 = jedis.get("k1");
System.out.println("获取到的字符串类型k1的值:" + v1);
// SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写)
// setex命令(语法:SETNX key value,表示只在键 key 不存在的情况下, 将键 key 的值设置为 value 。若键 key 已经存在, 则 SETNX 命令不做任何动作。
// setnx命令,简单来说就是:不存在就设置,存在就不设置
jedis.setnx("k2", "v2");
String v2 = jedis.get("k2");
System.out.println("获取到的字符串类型k2的值:" + v2);
//设置数据时指定key的过期时间(语法:SETEX key seconds value)
//将键 key 的值设置为 value , 并将键 key 的生存时间设置为 seconds 秒钟。如果键 key 已经存在, 那么 SETEX 命令将覆盖已有的值
//SETEX 命令的效果和以下两个命令的效果类似:SET key value && EXPIRE key seconds # EXPIRE设置生存时间,SETEX和这两个命令的不同之处在于SETEX是一个原子(atomic)操作, 它可以在同一时间内完成设置值和设置过期时间这两个操作
jedis.setex("k3", 5, "v3");
String v3 = jedis.get("k3");
System.out.println("获取到的字符串类型k3的值:" + v3);
//休眠5秒
Thread.sleep(5000);
System.out.println(jedis.get("k3")); // 这里k3过期了,返回值为null,如果k3键不存在,返回nil
//语法:PSETEX key milliseconds value,这个命令和 SETEX 命令相似, 但它以毫秒为单位设置 key 的生存时间, 而不是像 SETEX 命令那样以秒为单位进行设置
jedis.psetex("k4", 3000, "v4");
String v4 = jedis.get("k4");
System.out.println("获取到的字符串类型k4的值:" + v4);
System.out.println("k4还有" + jedis.pttl("k4") + "毫秒过期!");
//语法:GETSET key value,将键 key 的值设为 value , 并返回键 key 在被设置之前的旧值
jedis.getSet("k5", "v5");
String v5 = jedis.get("k5");
System.out.println("获取到的字符串类型k5的值:" + v5);//没有旧值,返回 nil
jedis.getSet("k6", "v6");
String v6 = jedis.get("k6");
System.out.println("获取到的字符串类型k6的值:" + v6);
//语法:INCR key,表示为键 key 储存的数字值加上一。如果键 key 不存在, 那么它的值会先被初始化为 0 , 然后再执行 INCR 命令
// incr命令 自增1
System.out.println(jedis.incr("k7"));//数字值在 Redis 中以字符串的形式保存
// decr命令 自减1
System.out.println(jedis.decr("k7"));
//语法:INCRBY key increment,为键 key 储存的数字值加上增量 increment
jedis.set("k8", "10");
jedis.incrBy("k8", 20);
String v8 = jedis.get("k8");
System.out.println("获取到的字符串类型k6的值:" + v8);//30
//语法:DECRBY key decrement,为键 key 储存的数字值减去增量 decrement
jedis.decrBy("k8", 5);
System.out.println("获取到的字符串类型k8的值:" + jedis.get("k8"));//25
//语法:MSET key value [key value …],同时为多个键设置值。如果某个给定键已经存在, 那么 MSET 将使用新值去覆盖旧值
jedis.mset("k9", "v9", "k10", "10");
//语法:MGET key [key …],返回给定的一个或多个字符串键的值。如果给定的字符串键里面, 有某个键不存在, 那么这个键的值将以特殊值 nil 表示
List<String> k9_k10 = jedis.mget("k9", "k10");
k9_k10.forEach(item -> {
System.out.println("获取到的mget的值:" + item);
});
//语法:MSETNX key value [key value …],当所有给定键都设置成功时, 命令返回 1 ; 如果因为某个给定键已经存在而导致设置未能成功执行, 那么命令返回 0
//当且仅当所有给定键都不存在时, 为所有给定键设置值。即使只有一个给定键已经存在, MSETNX 命令也会拒绝执行对所有键的设置操作。
//MSETNX 是一个原子性(atomic)操作, 所有给定键要么就全部都被设置, 要么就全部都不设置, 不可能出现第三种状态
Long mset = jedis.msetnx("k11", "v11", "k12", "v12");
System.out.println("MSETNX的值:" + mset);
//keys命令,列出所有的key
Set<String> set = jedis.keys("*");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//exists命令,检查某个key是否存在
boolean flag = jedis.exists("k1");
System.out.println("是否存在k1:" + flag);
//move命令,将当前库的key移动到给定的库db中,比如:move k1 1
long i = jedis.move("k1", 2);
System.out.println("移动k1到2号库:" + i);
//设置key的值的过期时间
String statusCode = jedis.set("k1", "v1");
System.out.println(statusCode);
// expire命令,k1键的值设置5秒后过期
jedis.expire("k1", 5);
System.out.println(jedis.get("k1"));
//查看key的过期时间
long ttl = jedis.ttl("k1");
System.out.println("k1的过期时间:" + ttl);
//type命令,查看key的值的数据类型
String type = jedis.type("k1");
System.out.println(type);
//休眠6秒
Thread.sleep(6000);
System.out.println(jedis.get("k1"));
//del命令,删除key
long del = jedis.del("k1");
System.out.println(del);
//切换7号库
jedis.select(7);
System.out.println(jedis.get("k100"));
}
}
Lettuce
是一个可伸缩线程安全的Redis客户端,多个线程可以共享同一个Redis Connection,它底层是利用优秀的Netty NIO
框架来实现网络通信的。Lettuce其实也是一个jar包,放到项目中,利用该jar包连接和操作redis。
Lettuce api操作和Jedis类似,一个redis命令对应一个jedis方法,只要熟悉redis的api,那也就相当于掌握了Lettuce 的api操作。
Github: https://github.com/lettuce-io/lettuce-core
官网: https://lettuce.io
【代码示例】
package cn.smilehappiness.client.lettuce;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.sync.RedisCommands;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
/**
* <p>
* 使用Lettuce Client操作redis基础使用
* Lettuce Client使用的时候还是很方便的,我们redis的所有命令,都可以用asyncCommands或者asyncCommands找到一个对应的方法,使用对应的方法操作即可
* <p/>
*
* @author smilehappiness
* @Date 2020/7/12 21:12
*/
public class LettuceClient {
/**
* 对redis的操作是同步的
*/
private static RedisCommands<String, String> syncCommands;
/**
* 对redis的操作是异步的
*/
private static RedisAsyncCommands<String, String> asyncCommands;
static {
//连接redis服务端
//连接格式:redis://[[email protected]]host:port[/databaseNumber] 其中中括号是可选的,也就是如果没有可以省略
RedisClient redisClient = RedisClient.create("redis://[email protected]:6379");
StatefulRedisConnection<String, String> connection = redisClient.connect();
//对redis的操作是同步的
syncCommands = connection.sync();
//对redis的操作是异步的
asyncCommands = connection.async();
//下面就可以使用syncCommands或者asyncCommands进行相关操作了
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//清空当前数据库中的所有 key,此命令从不失败
syncCommands.flushdb();
//清空整个 Redis 服务器的数据(删除所有数据库的所有 key ),此命令从不失败
syncCommands.flushall();
//string类型的举例
String k1Status = syncCommands.set("k1", "v1v1");
System.out.println(k1Status);
String v1 = syncCommands.get("k1");
System.out.println(v1);
/***************************************list类型举例************************************/
//从左边往list中放入元素
Long lSize = syncCommands.lpush("list", "1", "2", "3", "4");
System.out.println(lSize);
//从右边往list中放入元素
Long rSize = syncCommands.rpush("list", "8", "7", "6", "5");
System.out.println(rSize);
//语法:LRANGE key start stop,返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。
//下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
//你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
List<String> list = syncCommands.lrange("list", 0, 10);
list.forEach(System.out::println);
/***************************************set类型举例(无序不可重复)************************************/
//将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
//假如 key 不存在,则创建一个只包含 member 元素作成员的集合。当 key 不是集合类型时,返回一个错误
Long setSize = syncCommands.sadd("set", "11", "11", "14", "13", "11", "15", "18", "16", "19");
System.out.println(setSize);
//SMEMBERS key,返回集合 key 中的所有成员。不存在的 key 被视为空集合
Set<String> setList = syncCommands.smembers("set");
setList.forEach(System.out::println);
//异步操作:对redis的操作是异步的
RedisFuture<String> redisFuture = asyncCommands.set("async", "v1");
//get底层是阻塞的,需要等结果
String asyncValue = redisFuture.get();
System.out.println(asyncValue);
RedisFuture<String> stringRedisFuture = asyncCommands.get("async");
String stringAsyncValue = stringRedisFuture.get();
System.out.println(stringAsyncValue);
}
}
Redisson Client是2014年1月发布的开源项目,底层也是采用netty进行通信,该客户端目的是,让开发人员减少对Redis的关注
,从而让开发人员将精力更集中地放在处理业务逻辑上
,它提供很多分布式相关操作服务,例如,分布式锁,分布式集合、分布式队列等。
Github: https://github.com/redisson/redisson
官网: https://redisson.org
【代码示例】
package cn.smilehappiness.client.redisson;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* <p>
* 使用Redisson Client操作redis基础使用(这种方式不像Jedis和Lettuce那样,api方法和redis api对应,Redisson客户端目的减少开发人员对redis的关注,所以api方法调用时没有跟redis api对应)
* <p/>
*
* @author smilehappiness
* @Date 2020/7/12 21:40
*/
public class RedisRedissonClient {
private static RedissonClient redissonClient;
static {
//1、创建一个Config对象 , Redisson客户端使用fluent流式风格的编程,开发的时候比较方便
Config config = new Config();
//指定使用单节点部署方式
config.useSingleServer()
.setAddress("redis://127.0.0.1:6379")
.setPassword("123456789");
//2、创建一个Redisson对象
redissonClient = Redisson.create(config);
}
public static void main(String[] args) {
//清空当前数据库中的所有 key
redissonClient.getKeys().flushdb();
//清空整个 Redis 服务器的数据(删除所有数据库的所有 key )
redissonClient.getKeys().flushall();
//string类型的操作
redissonClient.getBucket("k1").set("v1");
Object object = redissonClient.getBucket("k1").get();
System.out.println(object);
//删除节点
redissonClient.getBucket("k1").delete();
//设置k1十秒后过期
redissonClient.getBucket("k1").set("v1");
redissonClient.getBucket("k1").expire(5, TimeUnit.SECONDS);
//list类型的操作
List<String> list = new ArrayList<>(Arrays.asList("2", "1", "4", "3", "5"));
boolean flag = redissonClient.getList("list").addAll(list);
System.out.println(flag);
//获取list这个key中的元素
List<Object> resultList = redissonClient.getList("list").readAll();
resultList.forEach(System.out::println);
//set类型的操作
Set<String> setList = new HashSet<>(Arrays.asList("11", "11", "14", "13", "11", "15", "18", "16", "19"));
redissonClient.getSet("mySet").addAll(setList);
redissonClient.getSet("mySet").forEach(item -> {
System.out.println("mySet元素:" + item);
});
//zset类型的操作
redissonClient.getScoredSortedSet("myZSet").add(1, "666");
redissonClient.getScoredSortedSet("myZSet").forEach(System.out::println);
System.out.println(redissonClient.getScoredSortedSet("myZSet").getScore("666"));
//hash类型的操作
redissonClient.getMap("myHash").put("userName", "smilehappiness");
redissonClient.getMap("myHash").forEach((k, v) -> {
System.out.println(k);
System.out.println(v);
});
//关闭客户端
redissonClient.shutdown();
}
}
连接Redis,不能总是用命令行客户端,Redis图形界面客户端,带来了极大的方便,主要有两个:
Redis Desktop Manager
官网:https://redisdesktop.com/
AnotherRedisDesktopManager
这个是国人写的另一个Redis图形界面客户端工具,用着还不错
https://github.com/qishibo/AnotherRedisDesktopManager
下载直通车:
Redis Desktop Manager
AnotherRedisDesktopManager
更新中…
更新中…
好啦,本篇到这里就介绍完毕了,有问题的可以评论交流哈,希望对老铁们有所帮助!
参考资料: http://redisdoc.com/
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家评论,一起探讨,代码如有问题,欢迎各位大神指正!
给自己的梦想添加一双翅膀,让它可以在天空中自由自在的飞翔!
安装简便轻松用 工作模式一键切换安装简便轻松用 工作模式一键切换用户希望无线网卡的安装配置约简单越好,繁琐的设置步骤只会失去用户的支持。那么腾达U6在实际的安装使用中,是否简单快速呢?下面就让我们剖析一下,腾达U6的安装配置流程,让用户对产品增加进一步的了解。首先,先让我们安装腾达U6的驱动程序。在腾达的官网就可以下载到驱动程序,或者使用随产品附赠的驱动光盘也可以安装驱动程序。一键安装自动安装打开...
如上图所示布局省份combobox的SelectedIndexChanged事件: public Form1() { InitializeComponent(); cmbprovince.SelectedIndex = 0;//默认选择省份里的第一项 } private void cmbprovince_SelectedIndexChanged(object sender, Even
云计算和大数据的区别:云计算注重资源分配,是硬件资源的虚拟化;而大数据是海量数据的高效处理。云计算和大数据之间并非独立概念,而是关系非比寻常,无论在资源的需求上还是在资源的再处理上,都需要二者共同运用。云计算和大数据的关系:云计算是基础,没有云计算,无法实现大数据存储与计算。大数据是应用,没有大数据,云计算就缺少了目标与价值。两者都需要人工智能的参与,人工智能是互联网信息系统有序化后的一种商业智能。而商业智能(即BI,国内典型代表BI厂商为亿信华辰)中的智能从何而来?方法之一就是通过大数据这个工具来对大
摘要目前有监督的人脸特征点检测方法需要大量的训练数据,且由于参数量大,容易在特定的数据集上过拟合。论文引入了半监督学习,其关键思想是从现有的大量未标记的人脸图像中生成隐含的人脸知识。首先在完全无监督的阶段,训练一个对抗自编码器通过低维的人脸嵌入来重建人脸。然后在监督学习阶段,将解码器与传输层交错,以重新处理彩色图像的生成,预测特征点热图。我们的框架(3FabRec)在几个常见基准上实现了最先进的性能,最重要的是,能够在极少训练集上保持惊人的准确性,少至仅10张图像。由于交错层只向解码器添加少量参数,整个推
一、常用命令列举 命令 类 说明 import ImportTool 将数据导入到集群 export ExportTool 将集群数据导出 codegen CodeGenTool ...
代数簇,是代数几何里最基本的研究对象。代数几何学上,代数簇是多项式集合的公共零点解的集合。代数簇是经典(某种程度上也是现代)代数几何的中心研究对象。 术语簇(variety)取自拉丁语族中词源(cognate of word)的概念,有基于“同源”而“变形”之意。历史上,代数基本定理建立了代数和几何之间的一个联系,它表明在复数域上的单变量的多项式由它的根的集合决定,而根集合是内在的几何对象。在此基...
推荐图书:《Python可以这样学》,ISBN:9787302456469,董付国,清华大学出版社,第9次印刷图书详情(京东):董付国老师所有图书均提供配套教学资源。==========...
先看效果图如何使用import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import android.app.Activity;import android.app.AlertDialo
最近需要重新使用vscode工具,需要重新下载这个工具,公司的网总是下载中断或者失败,究其原因大概是因为不是国内的服务器吧,在知乎上发现一个解决办法,现在整理下来,来帮助下载vscode受折磨的伙伴。首先在官网找到需要下载的文件,点击下载。在浏览器或者下载软件中就可以看到这么一个下载地址了,将其复制下来 这里没找到一个很好的复制方法,可以上下结合,只要最后保证下载连接的准确性和完整性即可。。然后将红框内的部分更换为如下内容:vscode.cdn.azure.cn<--------.
1、导入PySpark包2、创建SparkSession实例对象3、读取数据(Schema()信息)读取数据方法1读取数据方法24、查看DataFrame数据信息(显示完整【列名】不省略)6、SparkSQL模块中,结构化数据分析:DSL和sQL(filter)7、分组聚合(groupBy Rename)8、可视化展示(SparkSQL中DataFrame转...
1002. A+B for Polynomials (25)This time, you are supposed to find A+B where A and B are two polynomials.计算两个多项式的和。InputEach input file contains one test case. Each case occupies 2 lines, and e