关于redis 小白从入门到大神

文章目录
一.Redis 介绍
一.简介
二.发展历史
二.Redis 的安装与配置
三.Redis 命令
四.Redis 发布订阅模式
五.Redis 事务操作
六.Redis 性能测试
七.Redis 连接以及通信原理
八.Java 操作 Redis
九.Redis 其他进阶操作

Redis 官网
Redis 中国官网

Redis 官网在线测试

一.Redis 介绍
一.简介
Remote Directory Server(Redis)是一个开源的使用 ANSI C 语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言 API 的一个高性能的支持主从同步的 Key-Value 存储系统。通常被称为数据结构服务器,因为其支持的类型有:String,Hash,list,set,sorted set

feature

key-value 形式存储
支持数据持久化,可以将内存中数据保存在磁盘中,重启的时候可以再次加载进行使用
不仅仅支持简单的键值对类型的数据,同时还支持数据结构类型的存储(ist,set 等)
支持数据的备份,及 master-slave(主从模式)的数据备份
性能极高,read 11w 次/s,write 8w1k 次/s
支持数据类型丰富
所有操作皆为原子性,要么成功执行,要么失败完全不执行,单个操作是原子性,多个操作也支持事务,通过multi,exec 指令包起来
还支持 publish/subscribe,通知 key 过期等特性
二.发展历史
08 年的时候,意大利一家创业公司 Merzia 推出了一款基于 MySQL 的网站实时统计系统 LLOOGG,可是不久后该公司创始人 Salvatore Sanfilippo 便对 MySQL 的性能感到失望,于是他决定为 LLOOGG 系统量身打造一个数据库,并于 09 完成,这个数据库实际上就是 Redis 的前身,之后这个创始人不满足将这个数据库仅仅用于 LLOOGG,于是 Redis 开源了,并开始和 Redis 的另一名主要的代码贡献者 Pieter noordhuis 一起继续着 Redis 的开发直到如今。10 年的时候 VMware 开始赞助 Redis 的开发,Salvatore 和 Pieter 也于同年陆续加入 VMware 全职开发 Redis

二.Redis 的安装与配置
Redis Github 下载地址

windows 安装以及配置:

简单下载下来就行了,其支持 64 位或 32 位,可以配置 redis 目录的环境变量,方便命令启动

linux 安装以及配置:

如下载 2.8.17 压缩包并解压安装

$ wget http://download.redis.io/releases/redis-2.8.17.tar.gz
$ tar xzf redis-2.8.17.tar.gz
$ cd redis-2.8.17
$ make
之后 redis-2.8.17 目录下会出现 redis 的相关程序,具体位于安装目录下的 src 下

redis.conf 是 redis 默认配置文件

三.Redis 命令
redis 最常规的命令

windows 启动命令(启用默认的)

redis-server.exe redis.windows.conf
windows 启动命令(不启用默认的)

redis-server.exe
linux 启动命令(启用默认的)(先进入 redis 的 src 目录中)

$ cd src
$ ./redis-server …/redis.conf
linux 启动命令(不启用默认的)(先进入 redis 的 src 目录中)

$ cd src
$ ./redis-server
windows 设置键值对并取出键值(需要打开另一个 cmd)

redis-cli.exe -h 127.0.0.1 -p 6379
set myKey lalala
get myKey
linux 设置键值对并取出键值

$ cd src
$ ./redis-cli
redis> set myKey lalala
OK
redis> get myKey
“lalala”
删除 key

redis 127.0.0.1:6379> DEL myKey
redis.conf(linux)或者 redis.windows.conf(windows)可以用 CONFIG 命令查看设置

查看获取所有配置项

redis 127.0.0.1:6379> CONFIG GET *
修改配置并查看(直接是下面命令或者直接去改配置文件),如修改 loglevel 配置

redis 127.0.0.1:6379> CONFIG SET loglevel “notice”
OK
redis 127.0.0.1:6379> CONFIG GET loglevel
关于此配置文件中的参数说明,可以详见这里

Hash 存储

“Hash 存储”
redis 127.0.0.1:6379> HMSET myHash field1 “lalala” field2 “gagaga”
“OK”
redis 127.0.0.1:6379> HGET myHash field2
“gagaga”
List 列表存储

“List 存储(先从左边插再从右边插并显示)”
redis 127.0.0.1:6379> lpush myList1 myValue3 myValue2 myValue1
redis 127.0.0.1:6379> lrange myList1 0 2
“myValue1” “myValue2” “myValue3”
redis 127.0.0.1:6379> rpush myList2 myValue1 myValue2 myValue3
redis 127.0.0.1:6379> rrange myList2 0 2
“myValue1” “myValue2” “myValue3”
Set 集合

集合内元素具有唯一性

“Set 存储(Set 集合不存在会返回错误,若元素存在于 Set 集合中则返回 0 ,不存在 Set 集合中则返回 1)”
redis 127.0.0.1:6379> sadd mySet myValue1 myValue2 myValue2 myValue3
redis 127.0.0.1:6379> smembers mySet
“myValue1” “myValue2” “myValue3”
ZSet 有序集(Sorted Set)

ZSet 和 Set 一样也是 String 类型的元素集合,且不允许重复,不同的是每个元素都会关联一个 double 类型的分数,redis 正是通过该分数来为集合中成员进行从小到大的排序

“ZAset 存数据”
redis 127.0.0.1:6379> zadd myZSet 0 myValue1 1 myValue2 2 myValue3
redis 127.0.0.1:6379> ZRANGEBYSCORE myZSet 0 2
客户端启动

连接本地 redis 服务

$ redis-cli
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING
连接远程 redis 服务

$ redis-cli -h 127.0.0.1 -p 6379 -a “123456”
redis 127.0.0.1:6379>
redis m.xkfyz.com:6379> PING
redis-cli --raw可以有效的避免中文乱码

各种键命令

“删除 key”
DEL key
“序列化给定 key 并返回序列化的值”
DUMP key
“检查给定 key 是否存在”
EXISTS key
“为给定 key 设置过期时间”
EXPIRE key seconds
“为给定 key 设置 unix 类型时间戳的多去时间”
EXPIREAT key timestamp
“查找所有给定模式的 key”
KEYS pattern
“将当前数据库的 key 移动到给定数据库 db 中”
MOVE key db
“移除 key 的过期时间”
PERSIST key
“以 ms 为单位返回 key 的剩余过期时间”
PTTL key
“以 s 为单位返回 key 的剩余过期时间”
TTL key
“从当前数据库中随机返回一个 key”
RANDOMKEY
“修改 key 的名称”
RENAME key newkey
“仅当 newkey 不存在时候,才能将 key 改为 newkey”
RENAMENX key newkey
“返回 key 所存储的值的类型”
TYPE key
四.Redis 发布订阅模式
具体业务场景

异步消息通知场景(实际大多接口用回调通知,因为用Redis发布订阅限制条件苛刻,系统间必须共用一套Redis)

比如渠道在调支付平台的时候,我们可以用回调的方式给支付平台一个我们的回调接口来通知我们支付状态,还可以利用Redis的发布订阅来实现。比如我们发起支付的同时订阅频道pay_notice_ + wk (假如我们的渠道标识是wk,不能让其他渠道也订阅这个频道),当支付平台处理完成后,支付平台往该频道发布消息,告诉频道的订阅者该订单的支付信息及状态。收到消息后,根据消息内容更新订单信息及后续操作。

当很多人都调用支付平台时,支付时都去订阅同一个频道会有问题。比如用户A支付完订阅频道pay_notice_wk,在支付平台未处理完时,用户B支付完也订阅了pay_notice_wk,当A收到通知后,接着B的支付通知也发布了,这时渠道收不到第二次消息发布。因为同一个频道收到消息后,订阅自动取消,也就是订阅是一次性的。

所以我们订阅的订单支付状态的频道就得唯一,一个订单一个频道,我们可以在频道上加上订单号pay_notice_wk+orderNo保证频道唯一。这样我们可以把频道号在支付时当做参数一并传过去,支付平台处理完就可以用此频道发布消息给我们了。(实际大多接口用回调通知,因为用Redis发布订阅限制条件苛刻,系统间必须共用一套Redis)

调用支付接口 订阅频道 发布支付结果给 Redis 频道 将消息发给关注者 订单系统 支付系统 redis
任务通知场景

如系统跑批完成后通知指定的用户

订阅Redis频道 运行完成发布消息到频道 用户系统收到消息 用户系统 Redis 跑批系统
参数刷新加载场景

我们使用 Redis 无非是将系统中不怎么变动的,查询比较麻烦的数据给缓存起来,如系统首页轮播图,页面动态链接,一些系统参数,公共数据可以加载到 Redis 中,然后再有个后台管理系统去配置修改这些数据

如轮播图要增加一个图片,我们可以在后台系统中去加上,这样就完了吗?不,此时后台系统中加上了图片,但是 Redis 中还是老数据,要想 Redis 中的数据立即刷新成后台系统中的新数据,可以用到 Redis 的发布订阅机制来做到

订阅频道 后台修改数据 发布消息给指定频道 消息传给关注者 用户系统 Redis 后台系统 刷新或者点确认
实际命令演示

开两个 redis-cli 先创建可订阅的频道 redisChat 并订阅它

redis-cli 1(消息订阅者 1)

redis 127.0.0.1:6379> SUBSCRIBE redisChat
redis 127.0.0.1:6379> PSUBSCRIBE redisChannel*
redis-cli 2(消息订阅者 2)

redis 127.0.0.1:6379> SUBSCRIBE redisChat
redis 127.0.0.1:6379> PSUBSCRIBE redisChannel*
开第三个 redis-cli 用于发布信息到 redisChat 频道上

redis-cli 3(消息发布者)

publish redisChat ‘您有一条新信息’
publish redisChannelllll ‘您又有一条新信息’

这个时候前面的两个消息订阅者可以收到”您有一条新信息“,还可以收到”您又有一条新信息“
C 源码分析

pubsub_channels

redis 小白入门及深入讲解_第1张图片

源码中有个 pubsub.c文件,此文件中redisServer这个机构中有个数据结构是dict *pubsub_channels,key 为 channel 即订阅的频道, value 是一个 list 存放的是订阅者 client,这个 list 就是这个list *pubsub_patterns结构

pubsubSubscribeChannel 与 subscribeCommand

subscribe 原理很简单,就是创建一个频道,然后将当前 client 插入到这个频道(key)对应的 client 队列中

redis 小白入门及深入讲解_第2张图片

pubsubPublishMessage 与 publishCommand

publish 命令原理很简单,即找到字典中频道 key 对应的 value,也就是 client 队列,遍历这个队列给 client 发送消息

redis 小白入门及深入讲解_第3张图片

五.Redis 事务操作
单个 redis 命令执行时原子性的,但是 redis 没有在事务上增加任何维持原子性的机制,所以 redis 事务的执行不是原子性的,事务可以理解成一个打包的批量执行脚本,但是批量指令并非原子化操作,中间即使某条指令失败了,也并不会导致前面指令进行回滚,也不会造成后续指令不去执行

redis 事务可以一次执行多个命令,并且可以保证:

批量操作在发送 EXEC 命令前被放入队列缓存。
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败了,其余命令依然被执行。
在事务执行过程中,其他客户端提交的命令请求不会插入到事务执行命令中去。
redis 事务执行 3 个必经阶段:

开始事务
命令入队
执行事务
事务操作命令实例

“MULTI 用于开始一个事务”
redis 127.0.0.1:6379> MULTI
OK
“一系列事务操作添加到队里中”
redis 127.0.0.1:6379> SET name “LiMing”
QUEUED
redis 127.0.0.1:6379> GET name
QUEUED
redis 127.0.0.1:6379> SADD tag “a” “b” “c”
QUEUED
redis 127.0.0.1:6379>SMEMBERS tag
QUEUED

“通过 EXEC 来触发事务”
redis 127.0.0.1:6379www.xkfyz.com> EXEC
其他事务操作命令

“取消事务,放弃执行事务块内的所有命令”
DISCARD

“监视一个或多个 key”
WATCH key [key …]

“取消 WATCH 命令对所有 key 的监视”
UNWATCH
六.Redis 性能测试
此测试是在 redis 目录下执行,而不是 redis 客户端内部指令,下面会同时执行 10000 个 请求 来检测性能

$ redis-benchmark -n 10000 -q
序号 选项 描述 默认值
1 -h 指定服务器主机名 127.0.0.1
2 -p 指定服务器端口 6379
3 -s 指定服务器 socket
4 -c 指定并发连接数 50
5 -n 指定请求数 10000
6 -d 以字节的形式指定 SET/GET 值的数据大小 2
7 -k 1=keep alive 0=reconnect 1
8 -r SET/GET/INCR 使用随机 key, SADD 使用随机值
9 -P 通过管道传输 请求 1
10 -q 强制退出 redis。仅显示 query/sec 值
11 –csv 以 CSV 格式输出
12 -l 生成循环,永久执行测试
13 -t 仅运行以逗号分隔的测试命令列表。
14 -I Idle 模式。仅打开 N 个 idle 连接并等待。
七.Redis 连接以及通信原理
连接原理:

原理概述

redis 通过监听一个 TCP 端口或者 UNIX socket 的方式来接收来自客户端的连接,当一个连接建立之后,redis 内部会进行一下一些操作:

首先,客户端的 socket 会被设置成非阻塞态,因为 redis 在网络事件处理上采用非阻塞多路复用模型
然后,为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法
最后,创建一个可读的文件事件用于监听这个客户端 socket 的数据发送
最大连接数

最大连接数 maxclients 默认值是 10000,可在 redis.conf 中进行修改

客户端命令

S.N. 命令 描述
1 CLIENT LIST 返回连接到 redis 服务的客户端列表
2 CLIENT SETNAME 设置当前连接的名称
3 CLIENT GETNAME 获取通过 CLIENT SETNAME 命令设置的服务名称
4 CLIENT PAUSE 挂起客户端连接,指定挂起的时间以毫秒计
5 CLIENT KILL 关闭客户端连接
管道技术:

redis 是一种基于 client-server 模型以及请求响应协议的 tcp 服务,也就是说一个请求会遵循一下几步:client 先向 server 发送一个查询,client 同时监听 socket 返回,以阻塞模式等待服务器响应,服务器处理命令并将结果返回给客户端。redis 管道可以在 server 未响应时,client 可以继续向 server 发送请求,并最终一次性读取所有 server 的响应。管道技术显著提升了 redis 服务的性能

八.Java 操作 Redis
前置条件

已经安装了 redis 服务和 java redis 驱动(jedis.jar)

连接 redis 服务的 java 代码

public class RedisJava{
public static void main(String[] args){
//连接本地 redis 服务
Jedis jedis = new Jedis(“127.0.0.1”);
System.out.println(“连接成功”);
//查看服务是否运行
System.out.println(“服务正在运行:” + jedis.ping());
}
}
redis 存取操作

public class RedisJava{
public static void main(String[] args){
/* ========= 连接 redis ========= /
Jedis jedis = new Jedis(“www.xkfyz.com/zt 127.0.0.1”);
System.out.println(“连接成功”);
/
========= String 存取 ========= /
jedis.set(“string”, “字符串”);
System.out.println(“redis 存储的字符串是:” + jedis.get(“string”));
/
========= list 存取 ========= /
jedis.lpush(“list”, “表数据1”);
jedis.lpush(“list”, “表数据2”);
jedis.lpush(“list”, “表数据3”);
List list = jedis.lrange(“list”, “0”, “2”);
for(String str : list){
System.out.println(“列表数据为:” + str);
}
/
========= keys 读取 ========= /
Set keys = jedis.keys("
");
Iterator it = keys.iterator();
while(it.hasNext()){
String key = it.next();
System.out.println(key);
}
}
}
九.Redis 其他进阶操作
数据备份以及恢复

备份当前数据库

redis 127.0.0.1:6379> SAVE
将之前产生的备份文件 dump.rdb 移动到 redis 安装目录并启动服务即可

在后台备份

redis 127.0.0.1:6379> BGSave
连接服务密码查看及修改

查看是否设置了密码验证(默认情况这个参数里头是空的,意味无需通过密码验证直接可连接到 redis 服务)

127.0.0.1:6379> CONFIG get requirepass
修改密码

127.0.0.1:6379> CONFIG set requirepass “123456”
身份认证

127.0.0.1:6379> AUTH “123456”
OK
redis 分区结构

意义

通过多态计算机允许创造更大的数据库,拓展计算能力。涉及到多个 key 的操作是不被支持的,使用分区时,数据处理会变的复杂

分区理性

范围分区

映射一定范围的对象到特定的 redis 实例中。如 ID 0~10000 的用户会保存到 R0,10001~20000 的用户保存到 R1

哈希分区

这对任何 key 都适用,用一个 hash 函数将 key转换成一个数字,对这个整数取模,可以将其转化成 0~3 之间的数字(若存在 4 个分区),这样就可以存在指定的一个分区中了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值