NoSQL 数据库: 非关系型数据库 ,高并发,高可扩展,大数据存储问题解决方案
redis 非关系型数据库
redis 是用C语言开发的
开源高性能键值对数据库
键值存储数据库
应用场景
缓存(数据查询,短链接,新闻内容,商品内容)
聊天室在线好友列表
排行榜
网站访问统计
数据过期处理
安装步骤
由于 redis 是用C 语言写的,所以需要 gc
可通过 rpm -qa | grep gcc 来查询是否安装了gcc
安装 gcc : yum install gcc-c++
解压:tar -zxvf redis-5.0.7.tar.gz
进入redis文件夹
编译redis 源文件 :make
安装redis : make install PREFIX=/root/redis
redis 默认端口 :6379
配置redis :
将源码目录中的 redis.conf 复制到安装目录的bin下
启动redis,在bin 目录下:./redis-server redis.conf (需要读取配置文件)
关闭redis , ./redis-cli shutdown
设置外网访问
vi redis . conf
注释 bind 127.0.0.1 (连接白名单)
更改protected-mode yes 改为 no (保护模式)
访问
1.记得关闭防火墙 systemctl stop firewalld.service
2.添加阿里云端口配置
设置后台运行
vi redis . conf
更改 daemonize yes
在linux 连接 redis
./redis-cli -h 127.0.0.1 -p 6379
./redis-cli (表示本机,默认端口)
在windows desktop连接redis
安装Redis desktop manager
切换数据库 (0-15)
select 1
Redis 中存储数据时通过 key-value
value 数据类型
1.String
2.Hash
3.List
4.Set
5.SortedSet
String
存一个数据:set test 123
取一个数据:get test
存多个数据:mset name 123 addres 456 remarks 789
取多个数据:mget name address remarks
取值并赋值:getset 【key】 【value】
删除key:del 【key】
递增1:incr 【key】
递增指定数:incrby 【key】 【num】
递减1:decr 【key】
递减指定数:decrby 【key】 【num】
尾部追加 : append 【key】 "123"
获取字符串长度:strlen 【key】
层级关系:mset item:name 2 item:sex 3
Hash
存1个:hset user username 张三
取1个:hget user username
存x个:hmset user username 张三 age 20
取x个:hmget user usernmae age
取所有:hgetall user
该字段不存在时操作生效:hsetnx user username 李四
获取某个Hash对象的所有值:hgetall user
删除:hdel user age || hdel user name age
增加:hincrby user age 2
只获取 key :hkeys user
只获取value:hvals user
获取字段数量:hlen user
List
向列表左边增加元素:lpush list:1 1 2 3
向列表右边增加元素:rpush list:1 4 5 6
查看列表:lrange list:1 0 2 (查看0到x个 x可以为-1)
从列表左边弹出元素:lpop list:1
从列表右边弹出元素: rpop list:1
获取列表中的个数:llen list:1
获得指定索引的元素值:lindex l:list 2
设置指定索引的元素值: lset l:list 2 2
保留列表指定片段: ltrim l:list 0 2
元素从列表a转移一个到列表b中: rpoplpush a b
list 实际应用:商品评论列表
思路:
在Redis中创建商品评论列表
用户发布商品评论,将评论信息转成json存储到list中。
用户在页面查询评论列表,从redis中取出json数据展示到页面。
定义商品评论列表key:
商品编号为1001的商品评论key【items: comment:1001】
192.168.101.3:7001> LPUSH items:comment:1001 '{"id":1,"name":"商品不错,很好!!","date":1430295077289}' |
Set
集合中的数据是不重复且没有顺序
增加元素:sadd set a b c
删除元素:srem set c d
获得集合中的所有元素:smembers set
判断元素是否在集合中: sismember set a
集合的交集运算:sinter setA setB
集合的并集运算:sunion setA setB
获得集合中元素的个数:scard setA
从集合中随机弹出一个元素:spop setA
SortedSet
格式: 【 value : key 】
增加元素zadd scoreboard 80 zhangsan 89 lisi 94 wangwu
获取元素的值:zscore scoreboard lisi
删除元素:zrem scoreboard lisi
获得排名在某个范围的元素列表,从小到大:zrange scoreboard 0 2
获得排名在某个范围的元素列表,从大到小:zrevrange scoreboard 0 2
获得元素的分数:zrevrange scoreboard 0 2 WITHSCORES
获得指定分数范围的元素:ZRANGEBYSCORE scoreboard 90 97 WITHSCORES
增加某个元素的value:ZINCRBY scoreboard 4 lisi
获得集合中元素的数量:ZCARD scoreboard
获得指定value范围内的元素个数:ZCOUNT scoreboard 80 90
按照排名范围删除元素: ZREMRANGEBYRANK scoreboard 0 1
按照value范围删除元素:ZREMRANGEBYSCORE scoreboard 80 100
获取元素的排名,从小到大:ZRANK scoreboard lisi
获取元素的排名,从大到小:ZREVRANK scoreboard zhangsan
SortedSet实际运用:商品销售排行榜
需求:根据商品销售量对商品进行排行显示
思路:定义商品销售排行榜(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 |
其他命令
set test 1 设置test的值为1
get test 返回:1 获取test的值
EXPIRE test 5 设置test的生存时间为5秒
TTL test 返回:1 查看test的生于生成时间还有1秒
get test 返回:(nil) 获取test的值,已经删除
返回满足给定pattern 的所有key:keys mylist*
1) "mylist" 2) "mylist5" 3) "mylist6" 4) "mylist7" 5) "mylist8" |
确认一个key 是否存在 :exists 【 key 】 存在返回1,不存在返回0
删除一个key:del age
重命名key:rename age age_new
返回值的类型: type 【 key 】
连接java 测试
添加依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
测试
@Test
public void test( )
{
Jedis jedis = new Jedis("47.98.231.255",6379);
jedis.select(0);
System.out.println(jedis.get("test"));
jedis.close();
}
@Test
public void testJedisPool( )
{
JedisPool jedisPool = new JedisPool("47.98.231.255",6379);
Jedis jedis = jedisPool.getResource();
jedis.select(0);
System.out.println(jedis.get("test"));
jedis.close();
jedisPool.close();
}
事务
redis 事务是一个单独隔离的操作,按顺序指定。事务在执行过程中,不会被其他客户端发来的请求打断。
事务,把多个指令串联起来,防止别的命令插队。
multi:开启定义事务
exec:执行事务
discard:取消事务
在定义事务阶段,如果出现语法错误,整个事务,自动取消。
在执行事务阶段,如果出现运行时错误,事务忽略,继续执行。
watch :监视变量
当正在监视某个变量的事务中时,变量值在别的地方发生改变,事务取消
unwatch:取消所有的监视
并发请求操作:https://blog.csdn.net/weixin_40652498/article/details/104643521
测试:
@RequestMapping("/ms")
@ResponseBody
public String miaoSha(){
Random random = new Random();
String userid = String.valueOf(random.nextInt(50000)); //用户id
Jedis jedis = new Jedis("47.98.231.255",6379);
jedis.select(0);
//ab -c 10 -n 500 -k http://127.0.0.1:8080/redisday02miaoSha_war/msPage/ms
/*
商品String 商品名:数量
-1未开始
0秒杀完
x正在秒杀
商品名:ms:computer
set ms:computerNum -1
*/
//秒杀列表Set 商品名:用户1,用户2
//列表:ms:msBcomputer:computer
//sadd ms:computerMsList -1
jedis.watch("ms:computerNum");
//2.判断用户是否已经秒杀过
if(jedis.sismember("ms:computerMsList",userid)){
jedis.close();
System.out.println("已秒杀过");
return "yimiaosha";
}else
if( jedis.get("ms:computerNum").equals("-1") ){
jedis.close();
System.out.println("未开始");
return "weikaishi";
}else
if( jedis.get("ms:computerNum").equals("0") ){
jedis.close();
System.out.println("已秒杀完");
return "yimiaoshawan";
}
Transaction multi = jedis.multi();
//3.秒杀
multi.decr("ms:computerNum");
multi.sadd("ms:computerMsList",userid);
System.out.println("秒杀成功");
multi.exec();
jedis.close();
return "ok";
}
持久化
RDB,AOF
RDB:在指定时间间隔,将内存中的数据集快照写入到磁盘中(最后一次备份可能会丢失)
redis.conf 中,指定了持久化文件及文件所在目录
dbfilename:持久化文件
dir :持久化文件所在目录
save:save 【在多少秒】 【完成多少次操作】 :就会进行持久化
AOF:存储的是指令,以日志的方式记录下,每个写操作
appendonly no :开启AOF 模式 yes 开启,no 关闭
appendfilename "xx.aof" : AOF持久化文件
如果两个功能都开启,默认使用AOF
主从复制
主服务器:写。
从服务器:读。
一般一主二从模式,实现读写分离。
主从服务器数据自动同步,数据自动保持一致。
配置时:配从不配主
命令:info replication 查看主从复制相关信息
复制一份bin(redis)为 bin2 (从机)(一般从机是在另外一台机器上,这里是为了做演示)
修改从机配置 vi redis.conf
修改从机端口为(port):6380
从机配置主机服务 : replicaof <masterip主机ip> <masterport主机端口>
如果设置密码:masterauth <master-password> (可选)
清除从机中的持久化文件:rm -fr dump.rdb appendonly.aof
启动从机:./redis-server redis.conf
连接从机:./redis-cli -h 127.0.0.1 -p 6380
以后,主机发生的修改,从机就会自动备份
配置哨兵
在/root/redis/下新建 sentinel.conf文件
在配置文件中写:
sentinel monitor 【mymaster-名字随意】 127.0.0.1 6379 【1-至少有1台主机认为他dang了,才能认定为它dang了】
启动哨兵:
./redis-sentinel /root/redis/sentinel.conf
Redis 集群(没搞懂)
redis 集群的管理工具 redis-trib.rb 依赖于 ruby环境
安装ruby
yum install ruby
yum install rubygems
将 ruby 与 redis 接口(配置集群管理工具)上传到/usr/local
https://download.csdn.net/download/weixin_40652498/12206518
安装:gem install /usr/local/redis-3.0.0.gem
(没搞懂)