Redis数据库(二)

Redis数据操作

  • redis-benchmark测试以及操作命令
    Redis支持各种的数据类型,而且Redis操作数据的速度很快的。在Redis数据库里面有一个“redis-benchmark”性能测试工具,可以直接使用这个工具来观察Redis使用:

/usr/local/redis/bin/redis-benchmark –help

该命令所需要的参数如下:

 -h <hostname>      Server hostname (default 127.0.0.1)
 -p <port>          Server port (default 6379)
 -s <socket>        Server socket (overrides host and port)
 -a <password>      Password for Redis Auth
 -c <clients>       Number of parallel connections (default 50)
 -n <requests>      Total number of requests (default 100000)
 -d <size>          Data size of SET/GET value in bytes (default 3)
 --dbnum <db>       SELECT the specified db number (default 0)
 -k <boolean>       1=keep alive 0=reconnect (default 1)
 -r <keyspacelen>   Use random keys for SET/GET/INCR, random values for SADD
  Using this option the benchmark will expand the string __rand_int__
  inside an argument with a 12 digits number in the specified range
  from 0 to keyspacelen-1. The substitution changes every time a command
  is executed. Default tests use this to hit random keys in the
  specified range.
 -P <numreq>        Pipeline <numreq> requests. Default 1 (no pipeline).
 -e                 If server replies with errors, show them on stdout.
                    (no more than 1 error per second is displayed)
 -q                 Quiet. Just show query/sec values
 --csv              Output in CSV format
 -l                 Loop. Run the tests forever
 -t <tests>         Only run the comma separated list of tests. The test
                    names are the same as the ones produced as output.
 -I                 Idle mode. Just open N idle connections and wait.

范例;
模拟1000个客户端进行数据的处理
/usr/local/redis/bin/redis-benchmark -h 127.0.0.1 -p 6379 -c 1000 -d 10 -n 1000
此时的命令之中的具体参数含义如下:
-h : 要连接的redis服务器的地址
-p :要连接的redis的运行端口
-c :指的是模拟的客户端数量
-d:每一次操作的数据长度
-n:每一个用户发出的请求数量
/usr/local/redis/bin/redis-benchmark -h 127.0.0.1 -p 6379 -c 1000 -d 10 -n 1000 -t set
表示只针对set操作进行测试

这里写图片描述

表示每秒可以set 17241.38条数据

将测试结果输出到文件中

/usr/local/redis/bin/redis-benchmark -h 127.0.0.1 -p 6379 -c 1000 -d 10 -n 1000 >> /usr/redis.test

随后来观察一下当前的测试结果,会包含有如下的信息内容:

这里写图片描述
cd /usr/
more redis.test
根据提示去找:(看不见数据)
PING_INLINE :19230.77 requests per second
SET :21276.60 requests per second
GET :26315.79 requests per second
INCR : 增长 18181.82 requests per second(每秒18181.82操作)
LPUSH :21739.13 requests per second(list操作)
RPUSH”:2199.76 requests per second
LPOP”: 2311.76 requests per second(出栈)
“RPOP”: 2211.76 requests per second
“SADD” :数字追加 2211.76 requests per second
LPUSH: (need to benckmark LRANGE)2199.76 requests per second

LRANGE_100 (first 100 elements)

你会清楚的发现,Redis在整体的执行速度上的确是很快,毕竟现在虚拟机的配置水平是很低的
但是性能再强也是有瓶颈的

以上数据是Redis在测试中模拟出来的数据

Redis最大的特征在于可以进行各种数据类型的操作,包括字符串、数字、集合(List、Set、Hash)、这些操作支撑在一起才造就了Redis
清楚每种数据类型可以存储什么样的数据
redis性能测试只是在本地单节点下进行的,多节点一定很快吗?不一定:多节点不一定很快,因为多节点的话会出现代理,由A到B很快,但是如果A和B之间增加代理层,会变慢(增加了传输),但代理层的好处在于可以让Redis结点增多,直接连接的操作是最快的,没有之一,如果增加代理层操作,一定会在某些程度上造成延迟,但是这些延迟有时候是可以忽略掉的

  • 字符串数据操作

在之前使用的set、get命令操作都是字符串,而字符串支持的操作命令有如下几种:
redis命令是有提示的
这里写图片描述

KEY VALUE 为主

1.基本操作
在Redis里面有一个特别重要的命令,keys ,可以进行全部数据的列出
*表示数据的匹配(最有用的一个)
keys *
keys m*

这里写图片描述

1)设置新的数据
set **username-**mldn hello
redis可以存储的数据很多,所以设置有统一标记username-
查找时:
keys username-* 便于查找,所以设置数据一定要有规律,否则会混乱
2)取得对应的数据:
get username
如果在进行数据查询的时候没有对应的key的内容。则返回的是”(nil)”的数据
get username-mldn
get username-* 返回为(nil)
在数据取得的时候,没有*的通配,只有”keys”的命令提供有这一操作,
3)清空仓库:flushdb
keys * 为空

4)不覆盖设置内容:(setnx) setnx username-mldn happy
SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写
对于setnx的返回结果有如下两类: 0 (表示没有设置成功)和1 (设置成功)
0在语言中代表false;1代表true

如果你现在设置的两个数据的key的内容是相同的,默认情况下是会发生有覆盖的问题的
比如:
set username-mldn hello
set username-mldn admin
get username-mldn 返回admin
有时候不希望覆盖
setnx username-mldn happy
返回 (Integer) 0
setnx username-mldn2 happy
返回 (Integer) 1

这样的处理操作保证了数据设置更加安全(必须没有key值才能进行操作)

5)设置数据保存的有效时间:setex
现在就表示该设置的内容在10秒之后就会自动销毁
在实际使用之中验证码的信息保存就使用了此类数据类型,因为该类型的数据到点后自动消失
setex key time value
setex 110-code 10 8789 (保持10s)
超过10s无法获取key的value值

如果用传统数据库做,并发量一旦较大,会比较差劲,一些验证码的匹配都是nosql处理的。

在我们某一个key具备有指定的有效时间设置之后,实际上可以使用”ttl key”查看当前key值的剩余有效时间,如果该内容已经消失了,则返回-2,如果没有消失,则返回剩余的时间。或者在有效期内,使用persist key ,让该key值取消有效时间,此时再用ttl key命令查看,则返回的结果是-1

应用广泛

ttl 100-code (超时返回(Integer)-2)
否则返回该key的剩余有效时间

6)设置多个key的内容:(批量设置)
mset username-110 hello username-120 world username-119 cry
那么此时同时设置有三个key的信息。大部分情况下只设置一个.
如果此时设置有相同的的key的信息,那么默认会出现覆盖的value值
mset username-110 hello1 username-120 world1 username-119 cry1
7)如果不想使用覆盖的设置key的内容
msetnx username-110 hello1 username-120 world1 username-119 cry1
包含有一个重复key以及两个不重复的key值,则返回”0”,因为有一个key重复,所以返回0,并且所有的内容都不允许设置

msetnx username-110 hello2 username-1 world username-2 cry

包含全部新的key值和内容,现在表示成功返回1 ,表示成功存入
msetnx username-1 world username-2 cry

8)内容追加:
原有key : username-110 value:hello
append 的用法
append username-110 world 返回的当前字符串内容的长度10
get username-110 结果helloworld

9)取得指定key的内容长度
strlen usrname-110
返回 10

10)删除指定的数据内容:
原来有key值 username-110 和 username-119
此时执行
del username-110 username-119 username-99
返回2 (即成功执行的删除key的数量)
如果现在指定的key值不存在,也不会影响到程序的执行,只会删除存在的key的信息

设计合理

  • Hash数据类型
    Hash是一种最为常见的数据类型,其保存的数据类型为:”key=value” ,但是需要提示的是,这个时候的key与value并不是redis数据中的key和value。hash是作为一种数据类型,可以这样理解关系:redisKey = HashValue 利用咱们的hash类型可以保存更多的数据

这里写图片描述

1.设置一个Hash类型,保存一个用户的用户名和真实姓名:

结构:mid为用户名的保存的属性名称 mldn为真实的用户名
hset member-mldn mid mldn
hset member-mldn name smith
也就是说mldn用户下保存了两个数据,一个是他的登录名(mid),一个是他的真实姓名name
2.取得指定key中内容
取得指定key中的mid的数据:
hget member-mldn mid 得到 mldn
取得指定key中的name的数据:
hget member-mldn name 得到smith

相当于保存了复合结构

hset member-admin mid admin
hset member-admin name adminstrator
hset member-admin password 123
可以想象存储的是二维表

Hash与对象转换
这里写图片描述

如果想要在某一个数据的key上保存更多的内容,就要使用Hash类型来完成

3.默认情况下hset会进行覆盖,那么使用hsetnx就可以避免掉这个覆盖问题
设置重复数据:hsetnx member-admin mid hello (返回0) false
设置不重复数据 :hsetnx member-aa mid hello(返回1)true
这个时候keys *可以见到的内容仅仅是所有key的名称,比如:member-admin,member-aa

4.数据批量设置:
hmset member-pp name wusheng age 55 province hb

5.判断某个key的某个属性书否存在
hexists memeber-pp shcool 返回0
hexists memeber-pp age 返回1
6.获取全部的数据的成员个数:hlen取得全部数据的内容长度
hlen member-pp
取得的是属性的个数
7.删除指定key的内容
hdel member-pp age
hdel member-pp name
8.取得一个的hash成员的key(成员)的内容
hkeys member-mldn
返回 mid 和name (因为它只有这两个属性)
9.取得指定hash中的所有内容
hvals member-mldn
返回mldn和smith
10.需要取得key对应的value内容
hgetall member-mldn
返回 mid mldn name smith 竖着排列

它在进行数据排列的时候采用的模式为:hash-key,hash-value,hash-key,hash-value…

Hash类型的设计与程序的对象模型可以做转换

  • *数字操作
    现在已经接触了基本类型和Hash类型,可以发现,在整个的数据保存的时候都可以进行数字的保存,所以现在也可以针对数字进行各种处理,处理命令如下:

1.如果要进行数字的操作,那么我们肯定要设置两个数字的内容:
设置一个基本类型
set num 100 ;
设置一个Hash类型
存放hash中的购买的商品编号以及购买数量:
hset sc-mldn pid-72378 100

2.进行普通数据类型的数字操作:
1)自增1处理:incr num (随后会返回当前增长后的数据内容)
2)自增指定数(默认增长为1,现在要求增长为5):
incrby num 5
3)自减1处理:decr num
4)自减少指定的数据:decrby num 100

3.进行Hash数据类型的数字操作
hincrby
实际上整个数字操作里面只需要记住两个命令:incrby、hincrby就够了,可以写-1 即表示减1

hincry sc-mldn pid-72378 1或者
hincry sc-mldn pid-72378 -1 自减1

应用场景:购物场景购物车的使用

  • List的数据类型
    List数据类型是一种比较特殊麻烦的处理操作,在我们实际的项目开发里边,List就是一个链表结构,那么链表结构的时间复杂度是O(n),而且在进行链表数据处理的时候主要是进行内容的保存,节点的设置、递归遍历等。

这里写图片描述
List支持的操作命令:
1.(左边压入)创建一个描述关键字的List集合
lpush sks mldn java hello word happy cloud;
要想做数组的输出,就必须进行循环遍历或者迭代
push:属于入栈,栈的特点是先进后出,
2.进行指定范围的链表数据输出
lrange sks 0 2
输出三个值cloud,happy,word
lrange sks 0 -1
输出全部结果
3.(右边压入)进行入栈处理:
rpush sks 1 2 3 4 5 6 7
4.在指定元素(hello)前追加内容:
在指定元素前追加:
linsert sks before hello hello-before
在指定元素后追加:
linsert sks after hello hello-after
如果此时保存的集合内容存放有重复的数据,则以第一个数据为准
5.修改指定索引的数据
修改序号 (虽然序号是从1开始的,但实际对应list数组中是以)
lset sks 0 springboot
lset sks 1 boot

6.删除数据:lrem sks 1 hello(删除原有数据)
lrem sks 5 hello(5代表重复个数)
7.保留指定范围的数据
ltrim sks 0 9
删除数组元素中0-9返回内的数据将会被删除掉
范围编号不在0-9之间的所有数据将被删除掉
8.(栈顶)元素出栈
lpop sks (将会将栈顶元素进行出栈操作)
9.(栈尾/栈底)元素出栈
rpop sks
10.将移除的数据保存到另外一个集合中
rpoplpush sks dsk
表示将sks集合中的栈底的一个元素出栈,然后压入到dsk这个集合的栈顶
11.取得指定索引对应的数据
lindex 0(取得第一个栈顶元素的数据)

12.取得集合个数
llen sks

Redis支持栈的处理操作,性能很高

  • Set集合
    Set也是一种常见的数据类型,其最大的特征是基于数据的集合比对处理,例如:可以实现数据的交集,并集,差集(好友推荐的应用)

这里写图片描述

1.向集合之中追加新元素:
sadd user-mldn a b c d e;
此时向该集合中追加五个元素,可以把每一个元素想象成一个用户名
2.查询set集合处理
smembers user-mldn
List集合是有序的,Set是无序的
3.删除集合元素
srem user-mldn a;(元素重新排)
4.从集合中随机弹出一个元素(该元素会被自动进行删除处理)
spop user-mldn

5.返回两个集合的差集
准备出第一个集合:sadd user-mldn a b c d e
准备出第二个集合:sadd user-admin a c e x y z
差运算:sdiff user-mldn user-admin 显示 b,d
sdiff user-admin user-mldn 显示 y x z
6.保存差集的运行结果到另外一个集合中,
sdiffstore user-admin-mldn user-admin user-mldn
将user-admin于user-mldn两个用户的数据进行差集的计算处理,并且将结果保存到“user-admin-mldn”集合中
查看差集的保存: smembers user-admin-mldn

7.交集的运算
sinter user-mldn user-admin
具体相信的交集涉及到的信息一定需要在传统关系型数据库中进行处理
8.将我们的交集结果保存到指定集合中:
sinterstore user-admin-mldn-inter user-admin user-mldn
smembers user-admin-mldn-inter

9.并集运算:(相似度推荐)
sunion user-admin user-mldn;
10.将并集保存到指定集合中
sunionstore user-admin-mldn-union user-admin user-mldn;
smembers user-admin-mldn-union
存储的目的是方便存取和处理,不需要每次都在做相关交并差的操作

11.弹出数据到另一个集合中
smove user-mldn user-mldn-tmp a;
12.返回集合个数
scard user-mldn
13.判断指定的集合中是否包含有指定元素存在
sismember user-mldn a
sismember user-mldn b
返回0和1 0:false 1:true

14.随机返回集合中的一个数据 ,数据并不删除,只是显示
srandmember user-mldn 2
其中后面可以设置返回的数据个数,如果不设置默认为1

  • Sorted Set
  • Set集合的最大特征是可以进行数据比对,但是Set数据本身是属于无序的保存,所以如果需要进行数据的顺序保存,那么可以采用SortedSet,这个也不算是顺序保存,更多情况下该集合可以保存一个分数,而这个分数的操作就可以作为一些数据的统计结果出现。
    这里写图片描述

1.增加sortset的数据
zadd user-mldn 1 pid-1
zadd user-mldn 1 pid-2
zadd user-mldn 1 pid-3
zadd user-mldn 1 pid-4
zadd user-mldn 1 pid-5
现在假设这些商品的信息该用户只看了一次,所以每一个数据的分数为1
2.取得sortSet集合中的全部数据
显示所有的数据的元素:zrange user-mldn 0 -1
显示每一个元素和其对应的分数:zrange user-mldn 0 -1 withscores;
也可以输出指定范围的数据:zrange user-mldn 0 2 withscores;
3.从集合里面删除数据:
zrem user-mldn pid-1
4.元素分数的增长
zincrby user-mldn 5 pid-1
变成6 ,即返回当前增长后的分数数据内容
zincrby user-mldn 2 pid-2
zincrby user-mldn 6 pid-3
zincrby user-mldn 7 pid-4
zincrby user-mldn 8 pid-5

5.取得指定元素中的索引内容:
zrank user-mldn pid-1 (索引值是从0开始)
6.数据反转处理取得索引(顺序跌倒)
zrevrank user-mldn pid-1

7.反转后取得数据
zrevrange user-mldn 0 -1 withscores;
8.根据分数范围取得指定的数据
zrangebyscore user-mldn 3 6 withscores
闭区间处理zrangebyscore user-mldn 3 6 withscores包含了3和6
开区间处理:zrangebyscore user-mldn (3 (6 withscores
表示不包含3和6
设置一个范围:zrangebyscore user-mldn 1 10 withscores limit 0 2

9.取得指定分数范围的数据量
zcount user-mldn 2 8
10.取得指定集合中key的数量
zcard user-mldn
取得指定的分析的key:keys *

11.根据索引下标删除数据
zremrangebyrank user-mldn 0 5
zrange user-mldn 0 -1

  • Redis数据类型总结
    五大类型。Redis由于其处理的速度很快,某种程度上已经不完全属于数据库的支持了,所以对于数据类型可以给出一些总结:
    1.基本类型(String、int):基本类型的操作更加适合用户进行短期的数据存储,因为在实际的开发之中,字符串可以进行各种复杂的操作,而且字符串也可以描述出各种数据的含义。
    那么在实际的开发中,利用此类型实现Nginx的集群数据保存,Shiro的集群数据保存以及最重要的SringDatat数据保存(序列化)、json数据的保存
    SpringData牵扯到序列化数据,可以保存一组对象到数据库之中,这样数据操作很方便

2.hash类型:hash类型更多的情况下描述的是一个结构化的信息,但这种结构化的信息个人认为不如对象序列化好用,
利用springdata 可以很好的解决
至少需要知道Hash这样的类型可以进行内容的详细分类

3.list(栈、队列):在实际开发中可以利用此类型实现消息队列的功能或者进行缓冲的功能,很多公司有可能不直接使用消息队列中间件,而是使用redis代替

list比消息队列的优势在于可以消息队列内容持久化到磁盘文件系统中
这里写图片描述

4.Set数据类型:最大的支持功能在于集合的运算上,例如:相似度检测,好友推荐等等。都可以通过这种集合的操作处理来完成。应用案例(新浪微博)
5.SortedSet主要进行数据的流式分析
Hadoop大数据处理:
先数据归总,-集中分析,得到结果
就以用户浏览商品操作为例,

这里写图片描述

访问速度快,适合高并发的访问处理情况!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值