redis相关-程序员宅基地

技术标签: java  

redis

Redis 发布订阅_redis教程 中文官方帮助文档

redis入门

redis是什么?

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

reids会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

就是免费和开源!当下最热门的nosql技术!也被人们称为结构化数据库!

redis能干嘛?

1:内存存储、持久化、内存中是断电既失,所以说持久化很重要!

2:效率高、用于高速缓存!

3:发布订阅系统!

4:地图信息分析

5:计数器..计时器(浏览量!)

6:...

特性

1:多样的数据类型

2:持久化

3:集群

4:事务..

学习中用的东西

1:官网:reids.io

2:中文官网:redis.cn

windows安装

1:下载安装包:https://github,com/dmajkic/redis/releases

2:下再完接压缩:

4:开启redis,双击运行服务即可。redis-server.exe

redis默认端口号是6379

5:使用redis客户端来链接redis。redis-client.exe

Linux安装

1:下载安装包

2:解压redis安装包

tar redis文件包名称

3:进入解压后的文件,可以看到redis的配置文件

4:基本的环境安装

yum install gcc -c++
make 需要的文件回全部配置上,这个过程会很慢的,完成之后会看到多一个src文件
make install

5:redis的默认安装路径、都在usr下面

usr/local/bin 这个目录

6:将redis配置文件复制拷贝以下

没有文件可以建一个文件夹
cp/redis/config/新的文件名

7:redis默认不是后台运行的,修改配置文件

vim 配置文件名字 把下面改成yes

8:启动redis服务!

9:查看reids的进程是否开启

ps -ef|grep redis

10:如何关闭redis服务器

shutdown
exit
在执行进程是否开启的命令

基础的知识

redis默认有16个数据库 0-15 默认是0号数据库

可以看配置文件

可以使用select 进行切换数据库  select 0
set 键名 值  set a 1
get 键名      get a
dbsize 查看数据大小 
keys * 查看所有数据库所有的key
flush db 清空当前数据库
flushAll 清空所有数据库数据
​

redis是单线程的!

明白redis是很快的,官方表示,redis是基于内存操作,cpu不是reids性能瓶颈,redis的瓶颈是是根据机器的内存和网络带宽,既可以使用单线程来实现

reids是c语言写的,官方提供的数据为100000+ qps 完全不比同样是使用key-value的memecahce差!

redis为什么单线程还这么快!

1:误区1:高性能的服务器一定是多线程的

2:误区2:多线程(cpu上下文会切换!)一定比单线程效率高~

核心:redis是将所有的数据全部放在内存中的,所以说使用单线程效率就是最高的,

多线程(cpu上下文切换,耗时的操作!!)对于内存系统来说,如果没有上下文切换率就是最高的!,多次读写都是在同一个cpu上,在内存上是最佳的解决方案

redis端口号为什么是6379(粉丝效应,是一个女明星的名字)

五大数据类型

官方文档

翻译:Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串哈希表列表集合有序集合位图hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区

Redis-key

exists 键名 判断某个键是否存在 exists name
move 键名 数据库 移除当前数据库 move name 0
expire 键名 秒数 expire name 10
ttl查看过期时间 ttl name
type 键名 查看当前key是什么类型 type name

测试性能

redis-benchmark 是一个压力测试工具!

图片是在菜鸟编程找的!

简单测试下:

测试:100并发连接 100000请求

redis-benchmark -h localhost -p 6379 -c 100 -n 100000

String(字符串类型)

###########
set key1 v1 设置值
get key1 取值
keys * 查询所有键
exists key1 查看某个key是否存在
append 键名 值 往key追加值,当前key不存在就 set key append key1 v2
strlen 键名 获取字符串长度
#########
set views 0 设置一个浏览量
get views 获取浏览量
incr views 浏览量加一
decr views 浏览量减一
incrBy views 10 一次性加10,设置步长,指定增量 
decrBy views 5 一次性减5
########
getrange key 起始位置 结束位置  截取字符串 
getrange 0 -1 获取全部字符串 跟get key 一样
setrange key 位置 值 替换字符串
get key
#######
setex key 秒数 值 设置过期时间
setnx key 值 不存在设置(在分布式中常常使用!)
########
mset key1 值1 key2 值2 key3 值3 同时设置多个值
mget key1 key2 key3 同时获取多个值
msetnx key1 值1 key4 值4 msetnx 是一个原子性的操作,要么一起成功,一起失败 0失败,1成功

#######对象
set user:1 {name:zhangsan,age:3} 设置一个user:1对象值为 json字符来保存一个对象!
这里的key是一个巧妙的设计:user:{id}:{field},在redis中是完全可以的
mset user:1:name zhangsan user 1:age:2
mget user:1:name user:1:age
############
getset 先get在set 如果不存在值,则返回nuil
getset db redis 
get db
getset db mongdb 如果存在值,先获取原先的值,再赋值新值
get db

string类型的使用场景:计数器 、统计单位的数量、粉丝数、对象缓存存储

List

基本的数据类型、列表

在redis里面,我们可以把list玩成、栈、队列、阻塞队列!

所有list命令

#######
lpush 键名 值
lpush list one 将一个值或多个值插入列表的头部
lpush list two 二次插入
lpush list three 三次插入
lrange list 0 -1 查询所有
lrange list 0 1 根据区间查询具体的值
rpush list four 将一个值或多个值插入到列表的尾部
###########
lpop list 移除当钱队列最左边的值 
rpop list 移除当前队列最右边的值
########
lindex key index 通过下标获取list中的某一个值! 
lindex list 1

########
llen key 查询某个列表的具体长度
llen list
##########
移除指定的值!
lrem key 移除数量 值
lpush list three
lrem list 2 three
lrem list 1 one
##########
ltrim 截取的操作:
ltrim list 开始位置 结束位置
ltrim list 0 1 通过下标截取指定的长度,就只剩下截取的元素,其他元素已经移除!
#############
rpoplpush 移除列表最后一个元素,将他移动到新的列表中
rpoplpush 列表名  新的列表名 移除列表的最后一个元素,将他移动到新的列表中,如果没有则创会创建新的列表!
rpoplpush list mylist
lrange list 0 -1 旧列表查询
lrange mylist 0 -1 新列表查询
##########
exists 列表名称 判断值存不存在
lset list 0 item 进行元素替换,如果不存在则返回空,就相当于一个更新的操作
#########
linsert 将某个具体的value插入元素到前面或后面
linsert key before|after 哪个值 新值
linsert list before "值" "新值"

小结:实际上是一个链表,before node after left right 都可以插入值
如果key 不存在,创建新的链表
如果key存在,新增内容
如果移除了所有值,空链表,也代表不存在!
在两边插入或者改动值,效率最高!中间元素,效率低一点
可以做消息队列,它既可以做队列也可以做栈。

set(集合)

set中的值是不能重读的!

#########
sadd myset "hello" set集合中添加
smembers myset 查看指定set的所有值!
sismember 集合名称 值 
sismember myset hello 判断某一个值是不是在set集合中,没有则返回0!
###########
scard myset 获取set集合中内容元素的个数!
###########
srem myset hello 移除set集合指定元素

#########
set 无序不重复集合,抽随机

srandmember myset 随机抽选出一个元素
srandmember myset 2 随机抽出指定元素个数
###########
删除指定的key,随机的key
spop myset 随机删除一些set集合的元素!
##########
将一个值移动另外一个集合中
smove myset myset2 值
smove myset myset2 "hello"
#######
微博,b展,共同关注!(并集)
数字集合类
差集
交集
并集
sadd key1 a
sadd key1 b
sadd key2 a
sdiff key1 key2 查看差集
sinier key key2 交集 共同好可以实现
sunion key1 key2 并集

微博,a用户将所有关注的人放在一个set集合中!将他的粉丝也放在一个集合中!
共同爱好,共同关注推荐好友!(六度分隔理论)!

Hash(哈希)

Map集合,key -value! 这个值是一个map集合!

hset myhash field1 值 set一个具体的key-value
hget myhas field1 获取一个值
hmset myhash field1 值 filed2 值 set设置多个值
hmget myhash field1 field2 获取多个值
hgetall myhash 获取全部数据
hdel myhash field1 删除hash中指定key字段!对应的value值也随之删除!
#########
hlen myhash 获取hash表的字段数量,长度!
hexists myhash field1 判断hash中指定字段是否存在! 存在返回1 ,不在0
#########
hkeys myhash 只获取所有键
hvals myhash 只获得所有值
######
指定数量:
加一
hincr myhash field1 5
区间加
hincrby myhash field1 3
减一
hdecr myhash field1 1
区间减一
hdecrBy myhash field1 10
hsetnx myhash field4 hello 如果不存在则设置值,存在不会设置返回0

hash应用:
变更的数据:user 1:name jtw get user 1:name
可以做用户信息的保存,hash跟适合存储对象,string适合存字符串

Zset(有序集合)

在set基础上增加了一个键

zadd zset 1 one 添加一个值
zadd zset 2 two 3 three 添加多个值
zrange zset 0 -1
############
排序如何实现
zadd salary 2500 xiaohong 添加用户
zadd salary 5000 zhangsan
zrangebyscore key min max 
zrangebyscore salary -inf +inf withscores 按照薪水从小到大排序,withsocres是把薪水打印出来
######
移除rem中元素
zrange salary 0 -1
zrem salary xiaohong 移除某个元素
zcard salary 获取有序集合中的个数
#######
zrevrange salary 0 -1 反转
zcount salary 1 2 获取成员之间的数量

其余一些api,剩下的工作中需要可以查查官方文档!

案例思路:set排序,存储班级成绩表,工资表排序,排行榜应用实现!

三种特殊数据类型

Redis GEO

Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。

Redis GEO 操作方法有:

  • geoadd:添加地理位置的坐标。

  • geopos:获取地理位置的坐标。

  • geodist:计算两个位置之间的距离。

  • georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。

  • georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。

  • geohash:返回一个或多个位置对象的 geohash 值。

redis georedis3.2版本推出

geoadd 
规则:两级无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入
参数key(精度 纬度 城市名称)
有效的经度从-85.05112878度到85.05112878度
当坐标位置超出指定范围时,该命令将会返回一个错误。
#127.0.0.1:6379> geoadd china:city 39.90 116.40 beijin(error)ERR invalid longitude,1atitude pair 39.900000,116.400000

geoadd china:city 116.405285 39.904989 beijing 
geoadd china:city 121.472644 31.231706 shanghai 106.504962 29.533155 chongqing
geoadd china:city 114.085947 22.547 shenzhen 120.153576 30.287459 hangzhou


geopos
geopos china:city beijing chongqing 获取指定城市的经度纬度

geodist
两人之间的距离!
单位:
m表示单位为米
km表示单位为千米
mi表示单位为英里
ft表示单位英尺

geodist china:city beijing hangzhou km 查看北京到杭州的直线距离

附近的人(获得所有附近的人的地址,定位!)通过半径来查询
georadius
genradius china:city 110 30 1000km withlist withcoord 3  前提是城市必须存在当前集合中

georadiusbymember china :city shanghai 400 km 找出指定位置的其他元素

geohash返回一个元素或多个元素的geohash表示 返回11个字符串表示
geohash china:city beijing shanghai

zrange china:city 0 -1 查询所有元素
zrem china:city beijing 移除元素
基于zset

Hyperloglog

redis2.8.9就更新了Hyperloglog数据结构!

redis hyperloglog 基数统计的算法!

优点:

占用的内存是固定,2^64不同的元素的奇数,只废12Kb内存,如果说从内存角度来看hyperloglog可以考虑做第一位!

pfadd mykey a b c d e f g h i j 创建第一组元素
pfcount mykey 统计mykey中基数数量
pfadd mykey2 i j z x c v b n m
pfcount mykey2
pfmerge mykey3 mykey mykey2 合并两组 是一个并集的操作
pfcount mykey3 查看合并的数量

如果允许容错,可以使用hyperloglog,不允许则用set和自己需要的数据类型!

Bitmaps(位存储)

可以统计用户信息,活跃、不活跃!登录、未登录!打卡、未打卡!两个状态的可以使用bitmaps

bitmaps位图·,数据结构!都是操作二进制位来进行记录,就只有0和1两个状态!

365天=365bit 1字节=8bit 46个字左右!

使用bitmap来记录周一到周日的打卡!

查看某一天是否有打卡

统计的天数

bitcount sign #统计打卡天数,查看是否满勤

事务

事务的本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!

一次性、顺序性、排他性、执行一些命令

------队列 set set set 执行-----

redis事务没有隔离级别的概念!

所有命令在食物中,并没有直接被执行!只有发起执行命令的时候才会被执行!exec

redis单条命令式保存原子性,但是事务不保证原子性

redis的事务:

开启事务(multi)

命令入队

执行事务

正常执行事务!

multi 开启事务
set k1 v1
set k2 v2
exec 执行事务,每次执行完之后都会关闭事务,用的时候需要在开启

discard 取消事务 队列中的命令都不会执行!

编译型异常(代码有问题!命令有错!),事务中所有的命令都不会执行!

multi
set k1 v1
set k2 v2
set k3 v3
getset k3 错误的命令
exec 执行事务也不会执行

运行时异常(1/0)如果事务队列中存在语法性,那么执行的命令的时候,其他命令可以正执行的,错误命令会抛出异常

set k1 "v1"
multi
incr k1 
sey k2 v2
set k3 v3
get k3
exec 会抛出异常第一个命令,但其他命令依旧执行

监控! Watch(面试常问!)

悲观锁:

很悲观,什么时候都会出现问题,无论做什么都会加锁!

乐观锁:

很乐观,认为什么时候都不会出现问题,所以不会上锁,更新数据的时候去判断一下,在此期间是否有人修改过这个数据

获取version

更新的时候比较version

redis监视测试

#正常执行成功
set money 100
set out 0
watch money  监视money对象
multi 事务正常结束,数据期间没有发生变动,这个时候正常执行成功
decrby money 20
incrby out 20
exec
开启两个客户端
第一个客户端
watch money
multi
decrby money 10
incrby out 10
进入到第二个线程
get money
set money 1000
第一个线程
exe
第一个线程进行 exec 执行完之后回返回一个nil,因为第二线程修改了数据所有我们执行失败
测试多线程修改值,使用watch可以当做redis的乐观锁的操作!
解决方案 如果修改失败获取最新的值即可
unwatch 如果发现事务执行失败,就先解锁
watch money 在获取最新的监视
multi 开启事务
decrby money 1
incrby money 1
exec 先判断监视的值是否发生了变化,如果没有变化,那么可以执行成功,如有有变化就执行失败!

Jedis

我们要使用java操作redis

什么时jedis 是redis官方推荐的java连接开发工具,使用java操作redis中间件!如果你要使用java操作redis那么一定要对jedis十分熟悉

知其然并知其所以然,授人以渔!学习不能急躁,慢慢来会很快!

测试创建一个maven项目

<!--导入jedis的包-->
<dependency>
	<groupid>redis.clients</groupId>
	<artifactid>jedis</artifactid>
	<version>3.2.0</version>
</dependency>
<!--fastjson--->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactid>fastjson</artifactid>
	<version>1.2.62</version>
</dependency> 

public class testPing{
	public static void main(string[] args){
		//1:new Jedis 对象即可
		Jedis jedis=new Jedis("127.0.0.1",6379);
		//Jedis 所有的命令就是我们之间学习的所有执行!所以之前指令很重要!
		System.out.println(jedis.ping());
		
	}
}

连接成功输出pong

常用的API(用jedis.就行,跟上面的一样都)

String

List

Set

Hash

Zset

事务

后面没有写完!

SpringBoot整合

RedisConf

redis持久化

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/2302_78508024/article/details/136261645

智能推荐

JWT(Json Web Token)实现无状态登录_无状态token登录-程序员宅基地

文章浏览阅读685次。1.1.什么是有状态?有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session。例如登录:用户登录后,我们把登录者的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session。然后下次请求,用户携带cookie值来,我们就能识别到对应session,从而找到用户的信息。缺点是什么?服务端保存大量数据,增加服务端压力 服务端保存用户状态,无法进行水平扩展 客户端请求依赖服务.._无状态token登录

SDUT OJ逆置正整数-程序员宅基地

文章浏览阅读293次。SDUT OnlineJudge#include<iostream>using namespace std;int main(){int a,b,c,d;cin>>a;b=a%10;c=a/10%10;d=a/100%10;int key[3];key[0]=b;key[1]=c;key[2]=d;for(int i = 0;i<3;i++){ if(key[i]!=0) { cout<<key[i.

年终奖盲区_年终奖盲区表-程序员宅基地

文章浏览阅读2.2k次。年终奖采用的平均每月的收入来评定缴税级数的,速算扣除数也按照月份计算出来,但是最终减去的也是一个月的速算扣除数。为什么这么做呢,这样的收的税更多啊,年终也是一个月的收入,凭什么减去12*速算扣除数了?这个霸道(不要脸)的说法,我们只能合理避免的这些跨级的区域了,那具体是那些区域呢?可以参考下面的表格:年终奖一列标红的一对便是盲区的上下线,发放年终奖的数额一定一定要避免这个区域,不然公司多花了钱..._年终奖盲区表

matlab 提取struct结构体中某个字段所有变量的值_matlab读取struct类型数据中的值-程序员宅基地

文章浏览阅读7.5k次,点赞5次,收藏19次。matlab结构体struct字段变量值提取_matlab读取struct类型数据中的值

Android fragment的用法_android reader fragment-程序员宅基地

文章浏览阅读4.8k次。1,什么情况下使用fragment通常用来作为一个activity的用户界面的一部分例如, 一个新闻应用可以在屏幕左侧使用一个fragment来展示一个文章的列表,然后在屏幕右侧使用另一个fragment来展示一篇文章 – 2个fragment并排显示在相同的一个activity中,并且每一个fragment拥有它自己的一套生命周期回调方法,并且处理它们自己的用户输_android reader fragment

FFT of waveIn audio signals-程序员宅基地

文章浏览阅读2.8k次。FFT of waveIn audio signalsBy Aqiruse An article on using the Fast Fourier Transform on audio signals. IntroductionThe Fast Fourier Transform (FFT) allows users to view the spectrum content of _fft of wavein audio signals

随便推点

Awesome Mac:收集的非常全面好用的Mac应用程序、软件以及工具_awesomemac-程序员宅基地

文章浏览阅读5.9k次。https://jaywcjlove.github.io/awesome-mac/ 这个仓库主要是收集非常好用的Mac应用程序、软件以及工具,主要面向开发者和设计师。有这个想法是因为我最近发了一篇较为火爆的涨粉儿微信公众号文章《工具武装的前端开发工程师》,于是建了这么一个仓库,持续更新作为补充,搜集更多好用的软件工具。请Star、Pull Request或者使劲搓它 issu_awesomemac

java前端技术---jquery基础详解_简介java中jquery技术-程序员宅基地

文章浏览阅读616次。一.jquery简介 jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互 jQuery 的功能概括1、html 的元素选取2、html的元素操作3、html dom遍历和修改4、js特效和动画效果5、css操作6、html事件操作7、ajax_简介java中jquery技术

Ant Design Table换滚动条的样式_ant design ::-webkit-scrollbar-corner-程序员宅基地

文章浏览阅读1.6w次,点赞5次,收藏19次。我修改的是表格的固定列滚动而产生的滚动条引用Table的组件的css文件中加入下面的样式:.ant-table-body{ &amp;amp;::-webkit-scrollbar { height: 5px; } &amp;amp;::-webkit-scrollbar-thumb { border-radius: 5px; -webkit-box..._ant design ::-webkit-scrollbar-corner

javaWeb毕设分享 健身俱乐部会员管理系统【源码+论文】-程序员宅基地

文章浏览阅读269次。基于JSP的健身俱乐部会员管理系统项目分享:见文末!

论文开题报告怎么写?_开题报告研究难点-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏15次。同学们,是不是又到了一年一度写开题报告的时候呀?是不是还在为不知道论文的开题报告怎么写而苦恼?Take it easy!我带着倾尽我所有开题报告写作经验总结出来的最强保姆级开题报告解说来啦,一定让你脱胎换骨,顺利拿下开题报告这个高塔,你确定还不赶快点赞收藏学起来吗?_开题报告研究难点

原生JS 与 VUE获取父级、子级、兄弟节点的方法 及一些DOM对象的获取_获取子节点的路径 vue-程序员宅基地

文章浏览阅读6k次,点赞4次,收藏17次。原生先获取对象var a = document.getElementById("dom");vue先添加ref <div class="" ref="divBox">获取对象let a = this.$refs.divBox获取父、子、兄弟节点方法var b = a.childNodes; 获取a的全部子节点 var c = a.parentNode; 获取a的父节点var d = a.nextSbiling; 获取a的下一个兄弟节点 var e = a.previ_获取子节点的路径 vue