文章目录
一.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 个分区),这样就可以存在指定的一个分区中了

关于redis 小白从入门到大神相关推荐

  1. 小白 C++ 入门到大神发疯学习路线

    这篇文章实际上是我自己入门过程的总结,一个尽量少废话的C++入门指南.总结完忽然发现像个读书清单

  2. python从入门到大神系列手机_python从入门到大神---2、和Python编程相遇的日子

    python从入门到大神---2.和Python编程相遇的日子 一.总结 一句话总结: python2和python3是很不同的,连语法都不同,比如 print 函数打印结果 1.python中pip ...

  3. python从入门到大神---4、python3文件操作最最最最简单实例

    python从入门到大神---4.python3文件操作最最最最简单实例 一.总结 一句话总结: python文件操作真的很简单,直接在代码中调用文件操作的函数比如open().read(),无需引包 ...

  4. 数据库安全小白紧急求助论坛大神,困扰许久

    数据库安全小白紧急求助论坛大神,困扰许久 mircosoft SQL server 2008 R2怎样才能逃过甚至杜绝外来IP不断尝试SA密码? 求助各位论坛大神,封闭1433端口,设置数据库访问策略 ...

  5. python代码少的作品_原创 8行python代码展示程序员从入门到大神(或跑路)的全部状态...

    一行python代码可以做什么? 人生苦短,我用python.python的世界里无处不在的简洁和短小,往往一行代码可以实现很多有意思功能. 你敢想象你从入门python代码.网络达人.反重力怪才.爱 ...

  6. 8行python代码展示程序员从入门到大神(或跑路)的全部状态

    一行python代码可以做什么? 人生苦短,我用python.python的世界里无处不在的简洁和短小,往往一行代码可以实现很多有意思功能. 你敢想象你从入门python代码.网络达人.反重力怪才.爱 ...

  7. python类中的属性分为类属性和实例属性两种_python从入门到大神---1、初始化实例、类属性、方法...

    python从入门到大神---1.初始化实例.类属性.方法 一.总结 一句话总结: 方法不加括号是代码段:感觉python方法和js,php很类似,不加括号是代码段,加括号变成方法,比如f,f() 1 ...

  8. spring3.2入门到大神(备java基础、jsp、servlet,javaee精髓)-任亮-专题视频课程

    spring3.2入门到大神(备java基础.jsp.servlet,javaee精髓) 课程介绍         框架介绍,IoC思想.DI依赖注入.Bean的实例方式.Bean种类.Bean作用域 ...

  9. oracle入门到大神(备mysql、java基础、javaee必经之路)-任亮-专题视频课程

    oracle入门到大神(备mysql.java基础.javaee必经之路)-19178人已学习 课程介绍         Oracle10g的安装.orcale的基本概念介绍.命令行常用操作.Scot ...

最新文章

  1. 我为什么最终放弃了 Linux 桌面版的研发
  2. linux 常见服务端口
  3. 双链表的建立、求长、定位、插入、删除、输出和释放
  4. java web的运行方式_在运行 Javaweb项目时报错,不知道什么原因,百度了好多方法跟着人家的方法做了还是报错...
  5. VGA、DVI、HDMI、DP、Type-C不同视频接口有啥区别?
  6. 华尔街英语学习软件_华尔街英语核心课程功能升级 让学员学习之旅更高效
  7. No ExecutorFactory found to execute the application.
  8. 王者荣耀6月23服务器维护,王者荣耀6.23维护到什么时候?6月23日长枪掠火版本异常介绍...
  9. Shutter - 带有众多功能的屏幕截图工具
  10. IOS 代码控制控件始终居中
  11. C语言编程初体验 作文,我的理想是当编程师作文
  12. Kudu:支持快速分析的新型Hadoop存储系统
  13. MDK Pack安装包下载算法BUG
  14. Oracle 12c新特性--ASMFD(ASM Filter Driver)特性
  15. 光学计算机的工作原理,使用光学计算机的人工智能超分辨率
  16. 实体映射最强工具类:MapStruct 真香!
  17. Excel如何构建简单的透视表
  18. 直播换脸后,我们来搞搞微信QQ聊天换脸!| avatarify
  19. IDEA中HTML文档快速制作table表格快捷键方法
  20. 蓝桥杯试题算法训练之删除数组零元素——Python满分解答

热门文章

  1. Android开发我音乐App
  2. 新买的显示器怎么测试软件,新买的电视如何检测屏幕?记住这个方法
  3. Java 生成随机中文、英文姓名(下)
  4. 淘宝服务器哪个运营商速度快,三大运营商,谁的宽带网速最快?
  5. ASM+LINUX+ORACLE_11G安装
  6. 计算机起源于发展论文,关于计算机起源及发展的论文
  7. 我在创业游戏公司的一年
  8. NOJ 水獭看动漫 2001
  9. SET TIMING ON
  10. RESTful 标准接口教程