`学习目标

一、redis简介

1.1 redis介绍

Remote Dictionary Server (redis) 是一个由salvatore Sanfilippo开发的高性能的key-value数据库(存储系统)。Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存也可持久化的日志型,key-value数据库,并提供多种语言的api。它通常被称为数据结构服务器,因为值可以是字符串(String)、哈希(Map)、列表(List)、集合(Set)、有序集合()等类型。
Redis是一种运行速度很快、并发性能很强(高并发、高扩展、高性能),并且运行在内存上的Nosql数据库。
Nosql数据库和传统数据库相比的优势:
Nosql数据库无需事先为存储的数据建立字段,随时可以存储自定义的数据格式。
而在关系型数据库里,增删字段是一件非常麻烦的事情。如果非常大数据量的表,增加字段就是一个噩梦。

1.2 redis优势

性能极高 redis能读的速度是110000次/秒 ,写的速度是81000次/秒。
丰富的数据类型 redis支持二进制案例的String、List、hash、Set 以及 OrderedSet 数据类型操作。
原子 redis的所有操作都是原子性的,同时还支持对几个操作全并后的原子性执行。
丰富的特性- redis还支持public/subscribe、通知key过期等特性。

1.3 redis使用场景

  • 缓存
    热点数据(经常查询,但不修改或删除数据)
  • 分布式锁
    锁即在多线程环境下,对共享资源的访问造成的线程安全问题,通过锁的机制来实现资源访问互斥
  • token存储
  • 短信验证码存储
  • 全局唯一id
  • 排行榜
    redis的SortSet数据结构能轻松的搞定
  • 计算器/限速器
    利用redis中原子性的自增操作,可以统计类似用户点赞数、用户访问数。限速器如限制某个用户访问某个api的评率。常用的有抢购时,防止用户疯狂点击带来不必要的压力
  • 好友关系
    利用集合的一些命令。如求交集、并集、差集、可以方便搞定一些共同好友、共同爱好之类的功能。
  • 简单消息队列
  • 除了自带的发布订阅模式,也可以用list来实现一个队列机制如到货通知、邮件发送之类的需求,不需要高可靠,但是会带来非常大的db压力,完全可以用list来完成异步解耦。
  • session共享
    redis上存储Session ,无论用户落在哪台机器上都可以获取对应Session信息。

1.4 Nosql对比分析

redis和memcache

redis和memcache都是内存数据库。mencache可以缓存其他东西 如图片、视频等。
memcache数据结构单一,redis更丰富
虚拟内存。redis物理内存用完了,可以将一些很久没有用到的value交换到磁盘。
存储安全。memcache挂掉后,数据没有(没有持久化)redis可以定期保存到磁盘

redis和mongoDB

redis和mongodb 并不是竞争关系,更多的是一种协作共存的关系。
mongodb本质还是硬盘数据库,在复杂查询时仍然消耗大量的资源消耗,而且在处理复杂逻辑时仍然要不可避免的进行多次查询。这时就绪余redis或memcache这样的内存数据库来作为中间层进行缓存和加速。

二、redis入门

2.1 redis下载与安装

redis下载

redis下载地址:https://www.redis.net.cn/

linux进入指定redis linux 进入redis命令行_数据结构

Redis Desktop Manager 图形工具下载地址:https://redisdesktop.com/

linux进入指定redis linux 进入redis命令行_linux进入指定redis_02

redis安装

windows安装
Linux安装

redis linux 下基本操作

编辑redis.config文件
redis解压到/home/softwares/redis-7.2.4

vim /home/softwares/redis-7.2.4/redis.conf

在redis.conf文件中配置redis为后台运行

daemonize yes

以配置文件的方式启动
进入到usr/local.bin目录

cd /usr/local/bin
redis-server  /home/softwares/redis-7.2.4/redis.conf

这里我把conf 拷贝 /usr/local/bin 改名为redis7.conf
所以我的启动命令是

redis- server /usr/local/bin/redis7.conf

linux进入指定redis linux 进入redis命令行_数据结构_03

单实例关闭数据库

redis-cli shutdown

多实例关闭数据库

redis-cli - p 6379 shutdown

redis默认配置16个数据库

常用操作

检查6379端口是否在监听

netstat -lntp | grep 6379

检查redis 后台进程是否存在

ps -ef |grep redis

redis 为什么是6379端口
6379实在手机按键上MERZ对应的号码。而MERZ取自意大利歌女Alessia Merz的名字。

连接redis并测试

进入redis的命令终端

[root@localhost bin]# /usr/local/bin/redis-cli

在redis终端输入ping命令

127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>
读写数据

向k1保存数据,获取数据

127.0.0.1:6379> set k1 hello
OK
127.0.0.1:6379> get k1
"hello"
127.0.0.1:6379>
测试性能
[root@localhost bin]# redis-benchmark  -a 123456

清空数据库
清空当前数据库
清空所有数据库

[root@localhost bin]# /usr/local/bin/redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> flushall
OK
127.0.0.1:6379>

模糊查询

模糊查询keys命令 ,有三个通配符号:*、?、[ ].

匹配任意字符*

查询所有的键

127.0.0.1:6379> keys *
1) "k1"
2) "ke"
3) "k"
4) "k3"
5) "kh"
6) "k2"
7) "sdk"

模糊查询“k”开头的,后面随便匹配多少个字符

127.0.0.1:6379> keys k*
1) "k1"
2) "ke"
3) "k"
4) "k3"
5) "kh"
6) "k2"

模糊查询“h”为最后一位,前面随便多少个字符

127.0.0.1:6379> keys *h
1) "kh"
127.0.0.1:6379>

双* 模式,匹配任意多个字符,查询包含K的键

127.0.0.1:6379> keys *d*
1) "sdk"
127.0.0.1:6379>
匹配单个字符*

模糊查询“k”开头并且匹配一个字符

127.0.0.1:6379> keys k?
1) "k1"
2) "ke"
3) "k3"
4) "kh"
5) "k2"

查询字符长度为3 并且以s开头的键

127.0.0.1:6379> keys s??
1) "sdk"
匹配指定字符 【】

记得其他的字母,就第二个字母可能是d或f

127.0.0.1:6379> keys s[df]k
1) "sdk"
键操作

exist key :判断某个key是否存在 1表示存在 0 表示不存在

127.0.0.1:6379> exists k2
(integer) 1
127.0.0.1:6379> exists k20
(integer) 0

move key db:移动键到指定的库 1表示移动成功

move k2 4

ttl key:查看键还有多久过期 -1表示永不过期 -2 表示已过期

expire key 秒:为键设置过期时间(生命倒计时),单位是秒。

type key 查看键的数据类型

127.0.0.1:6379> type k1
string
127.0.0.1:6379> expire k1 60
(integer) 1
127.0.0.1:6379> ttl k1
(integer) 55
127.0.0.1:6379>

scan:渐进式遍历键
SCAN cursor [MATCH pattern] [COUNT count]
scan 参数提供了三个参数,第一个是 cursor 整数值(hash桶的索引值),第二个是 key 的正则模式, 第三个是一次遍历的key的数量(参考值,底层遍历的数量不一定),并不是符合条件的结果数量。第 一次遍历时,cursor 值为 0,然后将返回结果中第一个整数值作为下一次遍历的 cursor。一直遍历 到返回的 cursor 值为 0 时结束。
注意:但是scan并非完美无瑕, 如果在scan的过程中如果有键的变化(增加、 删除、 修改) ,那 么遍历效果可能会碰到如下问题: 新增的键可能没有遍历到, 遍历出了重复的键等情况, 也就是说 scan并不能保证完整的遍历出来所有的键, 这些是我们在开发时需要考虑的。