redis
1. NoSQL
NoSQL,中文称呼为非关系型数据库,它的全名Not only SQL。
NoSQL的出现并不是为了替代原有的关系型数据库,比如Oracle、SQLServer、MySQL、DB2等等,NoSQL的出现是为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案,所以它并不能替代关系型数据库,只能作为关系型数据库的一个良好补充,NoSQL需要关系型数据库结合,才能发挥真正的价值和意义。
2. NoSQL分类
NoSQL目前分为4大类,分别是
(1).键值存储数据库
(2).列存储数据库
(3).文档型数据库
(4).图形结构数据库
(1).键值存储数据库,主要是基于key-value的关系来保存,数据库中默认有一个哈希表,通过此表来完成一个特定的键指向一个特定的数据,key-value键值对模型优势在于简单易用,当需要大量数据处理的时候,优势非常明显,缺点在于如果仅仅只更新少量数据值的时候,效率有所下降。
常见的几种键值存储型NoSQL:Redis, Tokyo Tyrant, Voldemort, Oracle BDB。
(2).列存储数据库,通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak。
(3).文档型数据库,它同第一种键值存储相类似。但是此类数据库更多的时候存放内容都是半结构化的内容,比如存放JSON格式的数据。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDB. 国内也有文档型数据库SequoiaDB,目前已经开源。
(4).图形结构数据库,同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Graph.
3. Redis简介
REmote DIctionary Server(Redis)就是NoSQL中非常流行的一套非关系型数据库,它是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。由Salvatore Sanfilippo编写的key-value存储系统,redis的主要作用是在于构建高性能、可扩展的WEB应用服务,目前,Vmware在资助着redis项目的开发和维护。
Redis对于多种开发语言支持都非常完善,并提供多种语言的API,这也让它的热火度在全球领域都是只升不降的状态。
Redis中可以基于java常见的数据结构来完成对应的存储,所以在java领域应用非常广泛,Redis与其它键值数据存储相比,Redis有一组相对丰富的数据类型,可以基于string,map,list,set等类型来进行key-value存储。
Redis会将其数据库完全保存在内存中,仅使用磁盘进行持久化。Redis可以将数据复制到任意数量的从机中,进行分布式扩展。
4. Redis业务场景
在常见的业务场景中,最多使用redis的地方,就是系统服务缓存,比如查询数据,网页展示内容等。
另外一种常见使用的地方,就是分布式集群架构中的session分离。
其余会用到的地方,诸如IM(及时聊天工具)中的好友列表、系统服务中的任务列表、团购队列、抢票队列、下载排行、播放排行、热火度排行等等。
几乎在大型系统和海量数据的系统中,都有redis的身影。
5. Redis安装
下载最新的稳定版,然后放入到Linux系统中,然后通过解压缩命令释放
(官方说明,小版本为单数的是测试版,双数是正式版,举例4.1.1 4.2.1)
tar zxvf redis-4...tar.gz
然后进入解压以后的文件夹中
cd redis-4.0.2
开始执行编译
make
使用make MALLOC=libc命令安装
最后执行安装
make install
注意,安装软件需要root,通过su命令进入再执行此命令
这里需要注意,如果安装失败,因为linux中缺少组件造成,首先通过su进入root,然后依次安装下面的组件
yum install gcc
yum install gcc-c++
yum install tcl
安装成功以后,进入/usr/local/bin目录可以看到redis的文件列表,也可以通过输入whereis redis-server看到对应的路径
列表中,redis-cli是客户端,redis-server是服务端
6. 启动Redis服务
通过输入命令启动服务
/usr/local/bin/redis-server
通过输入命令启动客户端
/usr/local/bin/redis-cli
7. 关闭Redis服务
killall -9 redis-server
注意-9的两边有空格
8. Redis默认16个数据仓库
通过select number来切换数据仓库
第一个仓库是0
9. Redis清除所有数据命令
10. Redis数据插入、获取
获取所有的key值命令
语法:keys 或者keys name
注意这里的name是任意的名字可以被替换,代表查找key name的后缀
还需要注意的是redis的key区分大小写
(1)string类型
语法:SET key value
127.0.0.1:6379>set think hello
说明:存入一个key-value值
语法:GET key
127.0.0.1:6379>get think
说明:根据一个key得到一个value值
语法:GETSET key value
127.0.0.1:6379>getset think heihei
说明:替换一个key中的value值
语法:MSET key value [key value …]
127.0.0.1:6379>mset key1 val1 key2 val2
说明:同时加入多个key-value值
语法:MGET key [key …]
127.0.0.1:6379>mget key1 key2 key3
说明:同时获取多个key的value值
语法:DEL key
127.0.0.1:6379>del think
说明:删除一个或者多个key-value键值对
语法:INCR key(递增)
127.0.0.1:6379>incr key
说明:根据一个key中的整数数字+1,非整数数字会报错
语法:INCRBY key increment(增加指定的整数)
127.0.0.1:6379>incrby key 10
说明:根据一个key中的整数数字+指定整数,非整数数字会报错
语法:DECR key(递减)
127.0.0.1:6379>decr key
说明:根据一个key中的整数数字-1,非整数数字会报错
语法:DECRBY key decrement(减少指定的整数)
127.0.0.1:6379>decrby key 10
说明:根据一个key中的整数数字-指定整数,非整数数字会报错
语法:APPEND key value(在值的结尾追加内容)
127.0.0.1:6379>append think world
说明:根据一个key中的内容追加指定内容,如果key不存在,则生成一条新的k-v记录
语法:STRLEN key
127.0.0.1:6379>strlen str
说明:返回key对应值的长度,如果键不存在则返回0
特殊语法:支持key用冒号
127.0.0.1:6379>set user:id 1
127.0.0.1:6379>incr user:id
说明:key可以用冒号隔开命名,这样的好处,可以更容易理解key的含义,方便后期扩展使用
(2)hash类型
语法:HSET key field value
127.0.0.1:6379>hset user username thinknovo
说明:set一个对象,并set对应的属性和值
语法:HMSET key field value [field value …]
127.0.0.1:6379>hmset user username thinknovo password 123456
说明:为对象set多个属性、值(一个属性对应一个值)
语法:HSETNX key field value
127.0.0.1:6379>hsetnx user username think
说明:如果对象或者对象中的属性不存在时,才会执行set对象或者set对象中的属性和值
语法:HGET key field
127.0.0.1:6379>hmget user username
说明:获取一个字段值
语法:HMGET key field [field …]
127.0.0.1:6379>hmget user username password
说明:获取多个字段值
语法:HGETALL key
127.0.0.1:6379>hgetall user
说明:获取对象中所有属性和值
语法:HDEL key field [field …]
127.0.0.1:6379>hdel user username password
说明:删除一个或多个字段,返回结果显示被删除的个数,如果没有对应字段,返回0
语法:HINCRBY key field increment
127.0.0.1:6379>hincrby user password 5
说明:增加指定的大小,返回增加后的结果值
语法:HEXISTS key field
127.0.0.1:6379>hexists user username
说明:判断一个对象或者对象中某一个字段是否存在
语法:HKEYS key
127.0.0.1:6379>hkeys user
说明:获取对象中的所有字段名
语法:HVALS key
127.0.0.1:6379>hvals user
说明:获取对象中的所有字段值
语法:HLEN key
127.0.0.1:6379>hlen user
说明:获取对象中的字段个数
特殊语法:HMSET 支持冒号
127.0.0.1:6379>hmset item:100 age 10 sex man
说明:支持key用冒号
特殊语法:HGETALL 支持冒号
127.0.0.1:6379>hgetall item:100
说明:获取冒号对象中的所有key-value
(3)list类型
Redis的list是采用来链表来存储的,所以对于redis的list数据类型的操作,是操作list的两端数据来操作的。
语法:LPUSH key value [value …]
127.0.0.1:6379> lpush list 3
说明:向列表左边增加元素
语法:RPUSH key value [value …]
127.0.0.1:6379> rpush list 5 6
说明:向列表右边增加元素
语法:LRANGE key start stop
127.0.0.1:6379> lrange list 0 2(从0下标开始,查询0 1 2三个下标的数据)
127.0.0.1:6379> lrange list 0 -1(从0下标开始,查询所有下标的数据)
127.0.0.1:6379> lrange list -1 -1(从最后一个下标开始,后面的下标要大于最后一个下标)
说明:LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。
语法:LPOP key || RPOP key
127.0.0.1:6379> lpop list
127.0.0.1:6379> rpop list
说明:从列表两端移除元素,POP命令从列表左边或者右边弹出一个元素,会分两步完成:
第一步是将列表左边或者右边的元素从列表中移除
第二步是返回被移除的元素值。
语法:LLEN key
127.0.0.1:6379> llen list
说明:获取列表中元素的个数
语法:LREM key count value
127.0.0.1:6379> lrem list 3 9
说明:删除列表中指定的值,LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:
l 当count>0时,LREM会从列表左边开始删除指定个数。
l 当count<0时,LREM会从列表后边开始删除指定个数。
l 当count=0时,LREM删除所有值为value的元素。
注意:count代表总共删除指定的元素几个
语法:LINDEX key index
127.0.0.1:6379> lindex list 2
说明:获得指定索引的元素值
语法:LSET key index value
127.0.0.1:6379> lset list 2 2
说明:设置指定索引的元素值
语法:LTRIM key start stop
127.0.0.1:6379> ltrim list 0 2
说明:只保留当前list中的0,1,2下标内容,其余都删除
语法:LINSERT key BEFORE|AFTER pivot value
127.0.0.1:6379> lrange list 0 -1
1) “3”
2) “2”
3) “1”
127.0.0.1:6379> linsert list after 3 4
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) “3”
2) “4”
3) “2”
4) “1”
说明:向列表中插入元素,该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。
语法:RPOPLPUSH source destination
127.0.0.1:6379> rpoplpush list newlist
说明:将最后位的一个元素从一个列表转移到另一个列表中
(4)set类型
语法:SADD key member [member …]
127.0.0.1:6379> sadd set a b c
说明:增加/删除元素
语法:SREM key member [member …]
127.0.0.1:6379> srem set c d
说明:删除一个或者多个元素
语法:SISMEMBER key member
127.0.0.1:6379> sismember set a
说明:判断元素是否在集合中
语法:SDIFF key [key …]
127.0.0.1:6379> sadd setA 1 2 3
(integer) 3
127.0.0.1:6379> sadd setB 2 3 4
(integer) 3
127.0.0.1:6379> sdiff setA setB
1) “1”
127.0.0.1:6379> sdiff setB setA
1) “4”
说明:集合的差集运算A-B,属于A并且不属于B的元素构成的集合。
语法:SINTER key [key …]
127.0.0.1:6379> sinter setA setB
1) “2”
2) “3”
说明:集合的交集运算A ∩ B,属于A且属于B的元素构成的集合。
语法:SUNION key [key …]
127.0.0.1:6379> sunion setA setB
1) “1”
2) “2”
3) “3”
4) “4”
说明:集合的并集运算A ∪ B,属于A或者属于B的元素构成的集合
语法:SCARD key
127.0.0.1:6379> smembers setA
1) “1”
2) “2”
3) “3”
127.0.0.1:6379> scard setA
(integer) 3
说明:获得集合中元素的个数
语法:SPOP key
127.0.0.1:6379> spop setA
“1“
说明:从集合中弹出一个元素
注意:由于集合是无序的,所有SPOP命令会从集合中随机选择一个元素弹出
(5)sortedset类型
Sortedset又叫zset,是有序集合,可排序的,但是唯一。
Sortedset和set的不同之处,是会给set中的元素添加一个分数,然后通过这个分数进行排序。
语法:ZADD key score member [score member …]
127.0.0.1:6379> zadd scoreboard 80 zhangsan 89 lisi 94 wangwu
(integer) 3
127.0.0.1:6379> zadd scoreboard 97 lisi
(integer) 0
说明:增加元素,向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。
语法:ZSCORE key member
127.0.0.1:6379> zscore scoreboard lisi
“97”
说明:获取元素的分数
语法:ZREM key member [member …]
127.0.0.1:6379> zrem scoreboard lisi
(integer) 1
说明:删除元素,移除有序集key中的一个或多个成员,不存在的成员将被忽略。当key存在但不是有序集类型时,返回一个错误。
语法:ZRANGE key start stop [WITHSCORES]
127.0.0.1:6379> zrange scoreboard 0 2
1) “zhangsan”
2) “wangwu”
3) “lisi“
说明:获得排名在某个范围的元素列表,按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
语法:ZREVRANGE key start stop [WITHSCORES]
127.0.0.1:6379> zrevrange scoreboard 0 2
1) “ lisi “
2) “wangwu”
3) “ zhangsan “
说明:按照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素),如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数,例如下面的效果:
127.0.0.1:6379> zrange scoreboard 0 1 WITHSCORES
1) “zhangsan”
2) “80”
3) “wangwu”
4) “94”
语法:ZRANK key member
127.0.0.1:6379> ZRANK scoreboard lisi
(integer) 0
说明:获取元素的排名从小到大
语法:ZREVRANK key member
127.0.0.1:6379> ZREVRANK scoreboard zhangsan
(integer) 1
说明:从大到小
语法:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
127.0.0.1:6379> ZRANGEBYSCORE scoreboard 90 97 WITHSCORES
1) “wangwu”
2) “94”
3) “lisi”
4) “97”
127.0.0.1:6379> ZRANGEBYSCORE scoreboard 70 100 limit 1 2
1) “wangwu”
2) “lisi”
说明:获得指定分数范围的元素
语法:ZINCRBY key increment member
127.0.0.1:6379> ZINCRBY scoreboard 4 lisi
“101“
说明:增加某个元素的分数,返回值是更改后的分数
语法:ZCARD key
127.0.0.1:6379> ZCARD scoreboard
(integer) 3
说明:获得集合中元素的数量
语法:ZCOUNT key min max
127.0.0.1:6379> ZCOUNT scoreboard 80 90
(integer) 1
说明:获得指定分数范围内的元素个数
语法:ZREMRANGEBYRANK key start stop
127.0.0.1:6379> ZREMRANGEBYRANK scoreboard 0 1
(integer) 2
127.0.0.1:6379> ZRANGE scoreboard 0 -1
1) “lisi”
说明:按照排名范围删除元素
语法:ZREMRANGEBYSCORE key min max
127.0.0.1:6379> zadd scoreboard 84 zhangsan
(integer) 1
127.0.0.1:6379> ZREMRANGEBYSCORE scoreboard 80 100
(integer) 1
说明:按照分数范围删除元素
排行榜实例
需求:根据商品销售量对商品进行排行显示
思路:定义商品销售排行榜(sorted set集合),Key为items:sellsort,分数为商品销售量。
写入商品销售量:商品编号1001的销量是9,商品编号1002的销量是10
192.168.101.3:7007> ZADD items:sellsort 9 1001 10 1002
商品编号1001的销量加1
192.168.101.3:7001> ZINCRBY items:sellsort 1 1001
商品销量前10名:
192.168.101.3:7001> ZRANGE items:sellsort 0 9 withscores
11. keys命令
语法:keys
127.0.0.1:6379> keys mylist
127.0.0.1:6379> keys
说明:返回满足给定pattern 的所有key
语法:exists
127.0.0.1:6379> exists HongWan
说明:确认一个key 是否存在
语法:del
127.0.0.1:6379> del age
说明:删除一个或者多个key
语法:rename
127.0.0.1:6379[1]> rename age age_new
OK
说明:重命名key,上述实例age 成功的被我们改名为age_new
语法:type
redis 127.0.0.1:6379> type addr
string
redis 127.0.0.1:6379> type myzset2
zset
redis 127.0.0.1:6379> type mylist
list
说明:返回值的类型,这个方法可以非常简单的判断出值的类型
12. Redis设置生存时间
Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。
语法:EXPIRE key seconds
说明:设置key的生存时间(单位:秒)key在多少秒后会自动删除
语法:TTL key
说明:查看key剩余的生存时间
语法:PERSIST key
说明:清除生存时间
语法:PEXPIRE key milliseconds
说明:生存时间设置单位为:毫秒
13. Redis解决持久化失败
在linux中安装了redis以后,默认是没有dump.rdb文件的
而这个文件就是用来做磁盘本地持久化处理的,所以需要手动添加这个文件,可以从解压缩的文件中,cp直接拷贝一个到/usr/local/bin目录,然后再启动redis就可以正常持久化了。
14. 外部访问Redis服务
如果需要让外部访问到Linux中的redis服务,必须修改redis.conf配置文件两个位置
注意:如果当前管理员开启后无法被外部访问,就需要通过su切换到root超级管理员来开启服务
现在跳转到/usr/local/bin/目录
第一:bind 127.0.0.1 注释掉
第二:# requirepass foobared 打开注释,并且把foobared修改为自己想要的密码
然后在防火墙中,开启redis默认端口外部访问
第一步
firewall-cmd —permanent —add-port=6379/tcp
第二步
firewall-cmd —reload
启动服务时,需要加上对应的conf配置文件,才能生效
[thinknovo@thinknovo redis-4.0.9]$ src/redis-server ./redis.conf
在解压以后的根目录执行上述命令,注意此数据库中的数据不会与127.0.0.1中的数据共享。
客户端远程启动时,需要添加对应的密码,两种操作模式:
第一种
./redis-cli -h 192.168.3.100 -p 6379 -a 密码
第二种,分两步,先连接,再通过auth输入密码
./redis-cli -h 192.168.3.100 -p 6379
auth 密码
- 视图工具
RedisDesktopManager
下载视图工具RedisDesktopManager,对应有windows、mac和linu版本,一般在项目中,我们都在windows开发平台上查看数据结构,所以这里演示在windows中使用,其余版本类似
连接成功之后,会看到对应的数据库信息
Redis默认有16个储存空间,在没有手动设置空间的时候,默认使用第一个,我们可以对应开始添加键值对
16. jedis的使用
首先引入jedis的maven包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
在代码中开启jedis的连接
public class TestMain {
public static void main(String[] args) {
//连接本地的 Redis 服务 JedisPool jedisPool = new JedisPool(“192.168.3.100”, 6379);
System.**_out.println(“连接成功”);
Jedis jedis = jedisPool.getResource();
jedis.auth(“thinknovo”);
//查看服务是否运行 _System.out.println(“服务运行状态: “**+jedis.ping());
_// set get 设置/获取值_ _String result = jedis.set(**"thinks"**,**"123"**);<br /> System.**_out_**.println(**"result=" **+ result);<br /> System.**_out_**.println(**"get=" **+ jedis.get(**"thinks"**));
_//存储数据到列表中_ _jedis.lpush(**"list"**, **"2"**,**"3"**,**"4"**);<br /> _// 获取存储的数据并输出_ _List<String> list = jedis.lrange(**"list"**, 0 ,-1);<br /> **for**(**int **i=0; i<list.size(); i++) {<br /> System.**_out_**.println(**"列表项为: "**+list.get(i));<br /> }
_// 获取数据并输出_ _Set<String> keys = jedis.keys(**"*"**);<br /> Iterator<String> it = keys.iterator() ;<br /> **while**(it.hasNext()){<br /> String key = it.next();<br /> System.**_out_**.println(key);<br /> }<br /> }<br />}
17. spring4集成redis的使用
参考spring4redisdata1项目
这里要注意的是,redis集成对坏境要求极高,spring4必须使用jedis2.4.0以下,spring-data-redis必须使用2.0.0以下。
如果要装载bean对象,需要把bean对象实现序列化接口
18. spring5集成redis的使用
参考spring5redisdata2项目
这里要注意的是,redis集成对坏境要求极高,spring5必须使用jedis2.4.0以上,spring-data-redis必须使用2.0.0以上。
19. spring4集成redis的时间排序
把java日期对象装载redis中的时候,redis只会保存毫秒数,目的是为了后期日期排序,所以在取出日期对象的时候,需要手动转换一次,代码演示