NoSQL = Not Only 仅仅 是 SQL) , 也 解释为non-relational(非关系型数据库)。在 NoSQL 数据库中数据之间是无联系的,无关系的。数据的结构是松散的,可变的。
关系型数据库的瓶颈: 1) 无法应对每秒上万次的读写请求,无法处理大量集中的高并发操作。关系型数据的是 IO 密集的应用。硬盘 IO 也变为性能瓶颈 2) 表中存储记录数量有限,横向可扩展能力有限,一张表最大二百多列。纵向数据可承受能力也是有限的,一张表的数据到达百万级, 读写的速度就会逐渐的下降。面对海量数据,必须使用主从复制,分库分表。这样的系统架构是难以维护的。 大数据查询 SQL 效率极低,数据量到达一定程度时,查询时间会呈指数级别增长 3) 无法简单地通过增加硬件、服务节点来提高系统性能。数据整个存储在一个数据库中的。多个服务器没有很好的解决办法,来复制这些数据。 4) 关系型数据库大多是收费的,对硬件的要求较高。软件和硬件的成本花费比重较大。
大数据量,高性能 同样表现优秀。这得益于它的无关系性,数据库的结构简单。关系型数据库(例如 MySQL)使用查询缓存。这种查询缓存在更新数据后, 缓存就是失效了。在频繁的数据读写交互应用中。缓存的性能不高。
灵活的数据模型 NoSQL 无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。尤其在快速变化的市场环境中,用户的需求总是在不断变化的。
高可用 NoSQL 在不太影响性能的情况,就可以方便的实现高可用的架构。 NoSQL 能很好的解决关系型数据库扩展性差的问题。弥补了关系数据(比如 MySQL)在某些方面的不足,在某些方面能极大的节省开发成本和维护成本。 MySQL 和NoSQL 都有各自的特点和使用的应用场景,两者结合 使用。让关系数据库关注在关系上,NoSQL 关注在存储上
低成本
这是大多数分布式数据库共有的特点,因为主要都是开源软件,
(1) 无关系,数据之间是无联系的。
(1) 不支持标准的 SQL,没有公认的 NoSQL 标准
(3) 没有关系型数据库的约束,大多数也没有索引的概念
(4) 没有事务,不能依靠事务实现ACID.
(5) 没有丰富的数据类型(数值,日期,字符,二进制,大文本等)
MySQL 和NoSQL 都有各自的特点和使用的应用场景,两者结合 使用。让关系数据库关注在关系上,NoSQL 关注在存储上
Remote Dictionary Server(Redis) 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的 Key-Value 数据库. Key 字符类型,其值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型,每种数据类型有自己的专属命令。所以它通常也被称为数据结构服务器。
Redis 的作者是 Salvatore Sanfilippo,来自意大利的西西里岛,现在居住在卡塔尼亚。目前供职于 Pivotal 公司(Pivotal 是 Spring 框架的开发团队),Salvatore Sanfilippo 被称为Redis 之父。 官网:https://redis.io/ 中文:http://www.redis.cn/
Redis的历史: 2008年,意大利的一家创业公司Merzia推出了一款基于MySQL 的网站实时统计系统LLOOGG,然而没过多久该公司的创始人Salvatore Sanfilippo便开始对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。
不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望让更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。
Salvatore Sanfilippo自己也没有想到,短短的几年时间,Redis 就拥有了庞大的用户群体。2012年数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、知乎,国外如GitHub、Stack Overflow、Flickr、暴雪和Instagram,都是Redis 的用户。
VMware公司从2010年开始赞助Redis的开发,Salvatore Sanfilippo和Pieter Noordhuis也分别于同年的3月和5月加入VMware,全职开发Redis。
Redis的代码托管在GitHub上https://github.com/antirez/redis,开发十分活跃,代码量只有3 万多行。
Windows 版本的 Redis 是 Microsoft 的开源部门提供的 Redis。这个版本的 Redis 适合开发人员学习使用,生产环境中使用 Linux系统上的Redis
下载 官网:https://redis.io/ windows 版 本 : https://github.com/MSOpenTech/redis/releases
安装 下载的 Redis-x64-3.2.100.zip 解压后, 放到某个目录(例如d:\tools\),即可使用。目录结构:
启动 A、 Windows7 系统双击 redis-server.exe 启动Redis B、 Windows 10 系统 有的机器双击 redis-server.exe 执行失败,找不到配置文件,可以采用以下执行方式: 在 命 令 行 (cmd) 中 按 如 下 方 式 执 行 : D:\tools\Redis-x64-3.2.100>redis-server.exe redis.windows.conf 如图:
关闭 按ctrl+c 退出Redis 服务程序。
下载 wget http://219.238.7.66/files/502600000A29C8D5/download.redis. io/releases/redis-3.2.9.tar.gz
安装 A、上传redis-3.2.9.tar到linux系统。使用Xftp B、 解压redis-3.2.9.tar 到usr/local 目录 C、 查看解压后的文件
D、 编译Redis 文件,Redis 是使用 c 语言编写的。会使用gcc编译器。 在解压后的Redis 目录下执行 (cd /usr/local/redis-3.2.9) make 命令。
注意事项: 1) make 命令执行过程中可能报错,根据控制台输出的错误信息进行解决 2) 错误一:gcc 命令找不到,是由于没有安装 gcc 导致解决方式:安装gcc 编译器后在执行 make 命令
什么是 gcc ? gcc 是GNU compiler collection 的缩写,它是 Linux 下一个编译器集合( 相当于 javac ),是 c 或c++程序的编译器。 怎么安装gcc ? 使用yum进行安装gcc 。执行命令:yum -y install gcc
3) 错误二: error: jemalloc/jemalloc.h: No such file or directory 解决方式执行 make MALLOC=libc
开始执行make 出现错误: 没有gcc , cc 编译器 ,解决安装gcc 使用 yum -y install gcc 重新再编译 make 。注意:安装完 gcc 之后,再执行 make,先执行 make distclean 清理一下上次make 后产生的文件。 先执行 make distclean 再执行make 执行make 成功的标志 注意:在make执行之后再执行 make install,该操作则将 src下的许多可执行文件复制到/usr/local/bin 目录下,这样做可以在任意目录执行redis的软件的命令(例如启动,停止,客户端连接服务器等), make install 可以不用执行,看个人习惯。 查看make编译结果,cd src目录 cd src 在执行 ls 3) 启动Redis
启动方式:
① 前台启动 ./redis-server ② 后台启动 ./redis-server &
第①种 前台启动 启动Redis 的服务器端:切换到 src 目录下执行 redis-server 程序 redis 应用以前台的方式启动,不能退出当前窗口, 退出窗口,应用终止。
在其他窗口查看 redis 启动的进程 第②种 后台启动 src目录下执行 ./redis-server & 此时关闭窗口,查看redis进程, 依然存在。 查看redis进程 4) 关闭Redis
关闭方式: ① 使用redis 客户端关闭, 向服务器发出关闭命令 切换到 redis-3.2.9/src/ 目录,执行 ./redis-cli shutdown 推荐使用这种方式, redis 先完成数据操作,然后再关闭。 ② kill pid 或 者 kill -9 pid 这种不会考虑当前应用是否有数据正在执行操作,直接就关闭应用。 先使用 ps -ef | grep redis 查出进程号, 在使用 kill pid
Redis 客户端是一个程序,通过网络连接到 Redis 服务器, 在客户端软件中使用 Redis 可以识别的命令,向 Redis 服务器发送命令, 告诉Redis 想要做什么。Redis 把处理结果显示在客户端界面上。通过Redis 客户端和Redis 服务器交互。 Redis 客户端发送命令,同时显示 Redis 服务器的处理结果在。
redis-cli (Redis Command Line Interface)是 Redis 自带的基于命令行的Redis 客户端,用于与服务端交互,我们可以使用该客户端来执行redis 的各种命令。 两种常用的连接方式:
A、 直接连接 redis (默认 ip127.0.0.1,端口 6379):./redis-cli
在redis 安装目录\src, 执行 ./redis-cli 此命令是连接本机 127.0.0.1 ,端口 6379 的redis
B、 指定 IP 和端口连接redis:./redis-cli -h 127.0.0.1 -p 6379
-h redis 主机 IP(可以指定任意的 redis 服务器) -p 端口号(不同的端口表示不同的 redis 应用)
在redis 安装目录\src, 执行 ./redis-cli -h 127.0.0.1 -p 6379 例 1:
Redis Desktop Manager:C++ 编写,响应迅速,性能好。官网地址: https://redisdesktop.com/ github: https://github.com/uglide/RedisDesktopManager 使用文档:http://docs.redisdesktop.com/en/latest/
点击“DOWNLOAD” A、 安装客户端软件
在 Windows 系统使用此工具,连接 Linux 上或 Windows Redis , 双击此 exe 文件执行安装 安装后启动界面: B、 使用客户端连接 Linux 的Redis
连接Linux的Reids之前需要修改Redis服务器的配置信息。 Redis服务器有安全保护措施,默认只有本机(安装Redis的那台机器) 能够访问。配置信息存放在Redis安装目录下的redis.conf文件。修 改此文件的两个设置。 远程连接redis需要修改redis主目录下的redis.conf配置文件: ①、bind ip 绑定ip此行注释 ②、protected-mode yes 保护模式改为 no 使用 vim 命令修改 redis.conf 文件, 修改文件前备份此文件,执行cp 命令 执 行 vim redis.conf C、 使用 redis.conf 启动 Redis
修改配置文件后,需要使用配置文件重新启动 Reids,默认不加载配置文件。先关闭已经启动的 Redis ,使用以下命令启动Redis 在Redis 安装目录执行: ./redis-server …/redis.conf & D、 配置Redis Desktop Manamager(RDM),连接 Redis
在 RDM 的主窗口,点击左下的“Connect to Redis Server” 连接成功后:
A. Jedis
redis 的Java 编程客户端,Redis 官方首选推荐使用Jedis,jedis 是一个很小但很健全的 redis 的 java 客户端。通过 Jedis 可以像使用Redis 命令行一样使用 Redis。
⚫ jedis 完全兼容 redis 2.8.x and 3.x.x ⚫ Jedis 源码:https://github.com/xetorthio/jedis ⚫ api 文档:http://xetorthio.github.io/jedis/
B. redis 的其他编程语言客户端: C 、 C++ 、 C# 、 Erlang 、 Lua 、 Objective-C 、 Perl 、 PHP 、Python 、Ruby 、Scala 、Go 等 40 多种语言都有连接redis 的编程客户端
redis 默认为 16 个库 (在redis.conf 文件可配置,该文件很重要, 后续很多操作都是这个配置文件) redis 默认自动使用 0 号库
沟通命令,查看状态 redis >ping 返 回 PONG 解释:输入 ping,redis 给我们返回PONG,表示 redis 服务运行正常
查看当前数据库中key 的数目:dbsize 语法:dbsize 作用:返回当前数据库的 key 的数量。返回值:数字,key 的数量 例:先查索引 5 的key 个数, 再查 0 库的key 个数
redis 默认使用 16 个库
Redis 默认使用 16 个库,从 0 到 15。 对数据库个数的修改,在 redis.conf 文件中databases 16 4) 切换库命令:select db
使用其他数据库,命令是 select index
例 1: select 5
删除当前库的数据:flushdb
redis 自带的客户端退出当前 redis 连接: exit 或 quit
语法:keys pattern 作用:查找所有符合模式 pattern 的key. pattern 可以使用通配符。通配符: ⚫ * :表示 0-多个字符 ,例如:keys * 查询所有的key。 ⚫ ?:表示单个字符,例如:wo?d , 匹配 word , wood 例 1:显示所有的 key 例 2:使用 * 表示 0 或多个字符 例 3:使用 ? 表示单个字符 2) exists
语法:exists key [key…] 作用:判断key 是否存在 返回值:整数,存在 key 返回 1,其他返回 0. 使用多个 key,返回存在的key 的数量。 例 1:检查指定 key 是否存在 例 2:检查多个 key 3) expire
语法:expire key seconds 作用:设置key 的生存时间,超过时间,key 自动删除。单位是秒。返回值:设置成功返回数字 1, 其他情况是 0 。 例 1: 设置红灯的倒计时是 5 秒 4) ttl
语法:ttl key 作用:以秒为单位,返回 key 的剩余生存时间(ttl: time to live) 返回值: ⚫ -1 :没有设置 key 的生存时间, key 永不过期。 ⚫ -2 :key 不存在 ⚫ 数字:key 的剩余时间,秒为单位
例 1:设置 redlight 的过期时间是 10, 查看剩余时间 5) type
语法:type key 作用:查看key 所存储值的数据类型返回值:字符串表示的数据类型 ⚫ none (key 不存在) ⚫ string (字符串) ⚫ list (列表) ⚫ set (集合) ⚫ zset (有序集) ⚫ hash (哈希表)
例 1:查看存储字符串的 key :wood 例 2:查看不存在的 key
del语法:del key [key…] 作用:删除存在的key ,不存在的key 忽略。返回值:数字,删除的 key 的数量。
例 1:删除指定的 key
字符串类型是 Redis 中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据,序列化后的数据,JSON 化的对象甚至是一张图片。最大 512M。
哈希类型 hashRedis hash 是一个 string 类型的 field 和 value 的映射表, hash 特别适合用于存储对象。 3) 列表类型 list
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边) 4)集合类型set Redis 的 Set 是 string 类型的无序集合,集合成员是唯一的,即集合中不能出现重复的数据.
有序集合类型 zset (sorted set)Redis 有序集合zset 和集合set 一样也是string 类型元素的集合, 且不允许重复的成员。 不同的是zset 的每个元素都会关联一个分数(分数可以重复),redis 通过分数来为集合中的成员进行从小到大的排序。
字符串类型是 Redis 中最基本的数据类型,它能存储任何形式的字符串,包括二进制数 据,序列化后的数据,JSON 化的对象甚至是一张图片。
先测试能连接到 redis 服务器
set将字符串值 value 设置到 key 中 语法:set key value 查看已经插入的key
向已经存在的key 设置新的value,会覆盖原来的值 2) get
获取 key 中设置的字符串值语法: get key 例如:获取 username 这个key 对应的 value 3) incr
将 key 中储存的数字值加 1,如果 key 不存在,则 key 的值先被初始化为 0 再执行 incr 操作(只能对数字类型的数据操作) 语法:incr key 例 1:操作key,值增加 1
例 2:对非数字的值操作是不行的 4) decr
将 key 中储存的数字值减1,如果 key 不存在,则么 key 的值先被初始化为 0 再执行 decr 操作(只能对数字类型的数据操作)
语法:decr key 例1:不存在的key,初值为0,再减 1 。 例2:对存在的数字值的 key ,减 1 。先执行 incr index ,增加到 3 incr ,decr 在实现关注人数上,文章的点击数上。 5) append
语法:append key value 说明:如果 key 存在, 则将 value 追加到 key 原来旧值的末尾如果 key 不存在, 则将key 设置值为 value 返回值:追加字符串之后的总长度 例 1:追加内容到存在的 key
例 2:追加到不存在的 key,同 set key value
语法:strlen key 说明:返回 key 所储存的字符串值的长度返回值: ①:如果key存在,返回字符串值的长度 ②:key不存在,返回0
例 1:计算存在 key 的字符串长度
设置中文 set k4 中文长度 , 按字符个数计算 例 2:计算不存在的 key 2) getrange
语法:getrange key start end 作用:获取 key 中字符串值从 start 开始 到 end 结束 的子字符串,包括start 和 end, 负数表示从字符串的末尾开始, -1 表示最后一个字符 返回值:截取的子字符串。 使用的字符串 key: school, value: bjpowernode
例 1: 截取从 2 到 5 的字符
例 2:从字符串尾部截取,start ,end 是负数,最后一位是
例 3:超出字符串范围的截取 ,获取合理的子串
setrange语法:setrange key offset value 说明:用 value 覆盖(替换)key 的存储的值从 offset 开始,不存在的key 做空白字符串。 返回值:修改后的字符串的长度例 1:替换给定的字符串
例 2:设置不存在的 key
mset语法:mset key value [key value…] 说明:同时设置一个或多个 key-value 对返回值: OK
例 1:一次设置多个 key, value
mget语法:mget key [key …] 作用:获取所有(一个或多个)给定 key 的值返回值:包含所有key 的列表
例 1:返回多个 key 的存储值 例 2:返回不存在的 key
redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
语法:hset hash 表的key field value 作用:将哈希表 key 中的域 field 的值设为 value ,如果 key 不存在,则新建hash 表,执行赋值,如果有 field ,则覆盖值。 返回值: ①如果field 是hash 表中新field,且设置值成功,返回 1 ②如果field 已经存在,旧值覆盖新值,返回 0
例 1:新的field
例 2:覆盖旧的的 field
hget语法:hget key field 作用:获取哈希表 key 中给定域 field 的值 返回值:field 域的值,如果 key 不存在或者 field 不存在返回 nil
例 1:获取存在 key 值的某个域的值 例 2:获取不存在的 field
hmset语 法 :hmset key field value [field value…] 说明:同时将多个 field-value (域-值)设置到哈希表 key 中,此命令会覆盖已经存在的 field,hash 表 key 不存在,创建空的hash 表,执行 hmset. 返回值:设置成功返回 ok, 如果失败返回一个错误
例 1:同时设置多个 field-value
使用redis-desktop-manager 工具查看hash 表 website 的数据结构 例 2:key 类型不是 hash,产生错误
hmget语法:hmget key field [field…] 作用:获取哈希表 key 中一个或多个给定域的值 返回值:返回和field 顺序对应的值,如果 field 不存在,返回 nil
例 1:获取多个field 的值 5)hgetall 语法:hgetall key 作用:获取哈希表 key 中所有的域和值 返回值:以列表形式返回 hash 中域和域的值 ,key 不存在,返回空hash
例 1:返回key 对应的所有域和值 例 2:不存在的 key,返回空列表 6) hdel
语法:hdel key field [field…] 作用:删除哈希表 key 中的一个或多个指定域 field,不存在 field
直接忽略 返回值:成功删除的 field 的数量 例1:删除指定的field
语法:hkeys key 作用:查看哈希表 key 中的所有field 域 返回值:包含所有field 的列表,key 不存在返回空列表
例 1:查看website 所有的域名称 2)hvals 语法:hvals key 作用:返回哈希表 中所有域的值 返回值:包含哈希表所有域值的列表,key 不存在返回空列表 例 1:显示website 哈希表所有域的值
hexists语法:hexists key field 作用:查看哈希表 key 中,给定域 field 是否存在返回值:如果field 存在,返回 1, 其他返回 0
例 1:查看存在 key 中field 域是否存在
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)
语法:lpush key value [value…] 作用:将一个或多个值 value 插入到列表 key 的表头(最左边), 从左边开始加入值,从左到右的顺序依次插入到表头 返回值:数字,新列表的长度
例 1:将a,b,c 插入到 mylist 列表类型 在 redis-desktop-manager 显 示 插入图示:
例 2:插入重复值到 list 列表类型 在 redis-desktop-manager 显示
rpush语法:rpush key value [value…] 作用:将一个或多个值 value 插入到列表 key 的表尾(最右边), 各个 value 值按从左到右的顺序依次插入到表尾 返回值:数字,新列表的长度 例 1:插入多个值到列表 在 redis-desktop-manager 显示:
lrange语法:lrange key start stop 作用:获取列表 key 中指定区间内的元素,0 表示列表的第一个元素,以 1 表示列表的第二个元素;start , stop 是列表的下
标值,也可以负数的下标, -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 start ,stop 超出列表的范围不会出现错误。 返回值:指定区间的列表 例 1:返回列表的全部内容
例 2:显示列表中第 2 个元素,下标从 0 开始
lindex语法:lindex key index 作用:获取列表 key 中下标为指定 index 的元素,列表元素不删除,只是查询。0 表示列表的第一个元素,以 1 表示列表的第二个元素;start , stop 是列表的下标值,也可以负数的下
标, -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 返回值:指定下标的元素;index 不在列表范围,返回 nil
例 1:返回下标是 1 的元素 例 2:不存在的下标
llen语法:llen key 作用:获取列表 key 的长度 返回值:数值,列表的长度; key 不存在返回 0
例 1:显示存在 key 的列表元素的个数
语法:lrem key count value 作用:根据参数 count 的值,移除列表中与参数 value 相等的元素, count >0 ,从列表的左侧向右开始移除; count < 0 从列表的尾部开始移除;count = 0 移除表中所有与 value 相等的值。 返回值:数值,移除的元素个数
例 1:删除 2 个相同的列表元素
例 2:删除列表中所有的指定元素,删除所有的 java
lset语法:lset key index value 作用:将列表 key 下标为 index 的元素的值设置为 value。 返回值:设置成功返回 ok ; key 不存在或者 index 超出范围返回错误信息
例 1:设置下标 2 的value 为“c”。
linsert语法:linsert key BEFORE|ALFTER pivot value 作用:将值 value 插入到列表 key 当中位于值 pivot 之前或之后的位置。key 不存在,pivot 不在列表中,不执行任何操作。 返回值:命令执行成功,返回新列表的长度。没有找到 pivot 返回 -1, key 不存在返回 0。
例 1:修改列表arch,在值dao 之前加入 service
例 2:操作不存在的 pivot
redis 的Set 是 string 类型的无序集合,集合成员是唯一的,即集合中不能出现重复的数据
1)sadd
语法:sadd key member [member…] 作用:将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略,不会再加入。
返回值:加入到集合的新元素的个数。不包括被忽略的元素。 例 1:添加单个元素 例 2:添加多个元素 2) smembers
语法:smembers key 作用:获取集合 key 中的所有成员元素,不存在的 key 视为空集合 例 1:查看集合的所有元素 例 2:查看不存在的集合 3) sismember
语法:sismember key member 作用:判断 member 元素是否是集合 key 的成员返回值:member 是集合成员返回 1,其他返回 0 。
例 1:检查元素是否存在集合中 4) scard
语法:scard key
作用:获取集合里面的元素个数 返回值:数字,key 的元素个数。 其他情况返回 0 。 例1:统计集合的大小 例 2:统计不存在的 key 5) srem
语法:srem key member [member…] 作用:删除集合 key 中的一个或多个 member 元素,不存在的元素被忽略。 返回值:数字,成功删除的元素个数,不包括被忽略的元素。 例 1:删除存在的一个元素,返回数字 1 例 2:删除不存在的元素
语法:srandmember key [count] 作用:只提供key,随机返回集合中一个元素,元素不删除,依然在集合中;提供了 count 时,count 正数, 返回包含 count 个数元素的集合, 集合元素各不相同。count 是负数,返回一个count 绝对值的长度的集合,集合中元素可能会重复多次。 返回值:一个元素;多个元素的集合 例 1:随机显示集合的一个元素 例 2:使用count 参数, count 是正数 例 3:使用count 参数,count 是负数
语法:spop key [count] 作用:随机从集合中删除一个元素, count 是删除的元素个数。
返回值:被删除的元素,key 不存在或空集合返回 nil
例如 1:随机从集合删除一个元素
例 2:随机删除指定个数的元素
redis 有序集合zset和集合set一样也是string类型元素的集合,且不允许重复的成员。 不同的是 zset 的每个元素都会关联一个分数(分数可以重复), redis 通过分数来为集合中的成员进行从小到大的排序。
语法:zadd key score member [score member…] 作用:将一个或多个 member 元素及其 score 值加入到有序集合key 中,如果 member 存在集合中,则更新值;score 可以是整数或浮点数 返回值:数字,新添加的元素个数 例 1:创建保存学生成绩的集合
例 2:使用浮点数作为 score
语法:zrange key start stop [WITHSCORES] 作用:查询有序集合,指定区间的内的元素。集合成员按 score 值从小到大来排序。 start, stop 都是从 0 开始。0 是第一个元
素,1 是第二个元素,依次类推。以 -1 表示最后一个成员, -2 表示倒数第二个成员。WITHSCORES 选项让 score 和 value 一同返回。 返回值:自定区间的成员集合
例 1:显示集合的全部元素,不显示 score,不使用WITHSCORES 例 2:显示集合全部元素,并使用 WITHSCORES 例 3:显示第 0,1 二个成员
例 4:排序显示浮点数的 score
zrevrange语法:zrevrange key start stop [WITHSCORES] 作用:返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递减(从大到小)来排列。其它同zrange 命令。 返回值:自定区间的成员集合 例 1:成绩榜
zrem语法:zrem key member [member…]
作用:删除有序集合 key 中的一个或多个成员,不存在的成员被忽略 返回值:被成功删除的成员数量,不包括被忽略的成员。 例 1:删除指定一个成员 wangwu
zcard语法:zcard key 作用:获取有序集 key 的元素成员的个数 返回值:key 存在返回集合元素的个数, key 不存在,返回 0
例 1:查询集合的元素个数
语法:zrangebyscore key min max [WITHSCORES ] [LIMIT offset count]
作用:获取有序集 key 中,所有 score 值介于 min 和 max 之间 (包括min 和max)的成员,有序成员是按递增(从小到大) 排序。 min ,max 是包括在内 , 使用符号 ( 表示不包括。 min, max 可以使用 -inf ,+inf 表示最小和最大 limit 用来限制返回结果的数量和区间。 withscores 显示score 和 value 返回值:指定区间的集合数据
使用的准备数据
例 1:显示指定具体区间的数据 例 2:显示指定具体区间的集合数据,开区间(不包括 min,max)
例 3:显示整个集合的所有数据
例 4:使用 limit 增加新的数据:
显示从第一个位置开始,取一个元素。 2) zrevrangebyscore
语法:zrevrangebyscore key max min [WITHSCORES ] [LIMIT offset count]
作用:返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。其他同zrangebyscore
例 1:查询工资最高到 3000 之间的员工
zcount语法:zcount key min max 作用:返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量
例 1:求工资在 3000-5000 的员工数量
事务是指一系列操作步骤,这一系列的操作步骤,要么完全地执行,要么完全地不执行。 Redis 中的事务(transaction)是一组命令的集合,至少是两个或两个以上的命令,redis 事务保证这些命令被执行时中间不会被任何其他操作打断。
语法: multi 作用:标记一个事务的开始。事务内的多条命令会按照先后顺序被放进一个队列当中。 返回值:总是返回 ok
exec语法:exec 作用:执行所有事务块内的命令 返回值:事务内的所有执行语句内容,事务被打断(影响)返回 nil
discard语法:discard
watch语法:watch key [key …]
作用:监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 返回值:总是返回 ok
unwatch语法:unwatch 作用:取消 WATCH 命令对所有 key 的监视。如果在执
行 WATCH 命令之后, EXEC
DISCARD UNWATCH 了
事务的执行步骤: 首先开启事务, 其次向事务队列中加入命令,最后执行事务提交 例 1:事务的执行: 1)multi : 用multi 命令告诉Redis,接下来要执行的命令你先不要执行,而是把它们暂时存起来 (开启事务) 2)sadd works john 第一条命令进入等待队列(命令入队) 3)sadd works rose 第二条命令进入等待队列(命令入队) 4) exce 告知redis 执行前面发送的两条命令(提交事务) 查看works 集合
事务执行 exec 之前,入队命令错误(语法错误;严重错误导致服务器不能正常工作(例如内存不足)),放弃事务。 执行事务步骤: 1)MULTI 正常命令 2)SET key value 正常命令 3)INCR 命令语法错误 4)EXEC 无法执行事务,那么第一条正确的命令也不会执行,所以key 的值不会设置成功 结论:事务执行 exec 之前,入队命令错误,事务终止,取消,不执行。
事务执行 exec 命令后,执行队列命令,命令执行错误,事务提交 执行步骤: 1) MULTI 正常命令 2) SET username zhangsan 正常命令 3) lpop username 正常命令,语法没有错误,执行命令时才会有错误。 4) EXEC 正常执行 ,发现错误可以在事务提交前放弃事务,执行discard. 结论:在 exec 执行后的所产生的错误, 即使事务中有某个/某些命令在执行时产生了错误, 事务中的其他命令仍然会继续执行。 Redis 在事务失败时不进行回滚,而是继续执行余下的命令。 Redis 这种设计原则是:Redis 命令只会因为错误的语法而失败(这些问题不能在入队时发现),或是命令用在了错误类型的键上面,失败的命令并不是 Redis 导致,而是由编程错误造成的,这样错误应该在开发的过程中被发现,生产环境中不应出现语法的错误。就是在程序的运行环境中不应该出现语法的错误。而 Redis 能够保证正确的命令一定会被执行。再者不需要对回滚进行支持,所以 Redis 的内部
放弃事务 执行步骤:
MULTI 开启事务SET age 25 命令入队SET age 30 命令入队DISCARD 放弃事务,则命令队列不会被执行Redis 的watch 机制
A. Redis 的WATCH 机制
WATCH 机制原理: WATCH 机制:使用 WATCH 监视一个或多个 key , 跟踪 key 的value 修改情况,如果有key 的value 值在事务EXEC 执行之前被修改了, 整个事务被取消。EXEC 返回提示信息,表示事务已经失败。
WATCH 机制使的事务EXEC 变的有条件,事务只有在被WATCH 的 key 没有修改的前提下才能执行。不满足条件,事务被取消。使
用 WATCH 监视了一个带过期时间的键, 那么即使这个键过期了, 事务仍然可以正常执行
大多数情况下, 不同的客户端会访问不同的键, 相互同时竞争同一key 的情况一般都很少, 乐观锁能够以很好的性能解决数据冲突的问题。
B. 何时取消key 的监视(WATCH)?
① WATCH 命令可以被调用多次。对键的监视从 WATCH 执行之后开始生效,直到调用 EXEC 为止。不管事务是否成功执行, 对所有键的监视都会被取消。 ② 当客户端断开连接时, 该客户端对键的监视也会被取消。 ③ UNWATCH 命令可以手动取消对所有键的监视
C.WATCH 的事例 执行步骤: 首先启动redis-server , 在开启两个客户端连接。 分别叫 A 客户端 和 B 客户端。 启动Redis 服务器
A 客户端(红色):WATCH 某个key ,同时执行事务
B 客户端(黄色):对 A 客户端WATCH 的key 修改其value 值。 1) 在A 客户端设置 key : str.lp 登录人数为 10 2) 在A 客户端监视 key : str.lp 3) 在A 客户端开启事务 multi 4) 在A 客户端修改 str.lp 的值为 11 5) 在B 客户端修改 str.lp 的值为 15 6)在A 客户端执行事务 exec 7)在 A 客户端查看 str.lp 值,A 客户端执行的事务没有提交, 因为WATCH 的str.lp 的值已经被修改了, 所有放弃事务。
例 1:乐观锁
持久化可以理解为存储,就是将数据存储到一个不会丢失的地方, 如果把数据放在内存中,电脑关闭或重启数据就会丢失,所以放在内存中的数据不是持久化的,而放在磁盘就算是一种持久化。
Redis 的数据存储在内存中,内存是瞬时的,如果 linux 宕机或重启,又或者 Redis 崩溃或重启,所有的内存数据都会丢失,为解决这个问题,Redis 提供两种机制对数据进行持久化存储,便于发生故障后能迅速恢复数据。
Redis Database(RDB),就是在指定的时间间隔内将内存中的数据集快照写入磁盘,数据恢复时将快照文件直接再读到内存。 RDB 保存了在某个时间点的数据集(全部数据)。存储在一个二进制文件中,只有一个文件。默认是 dump.rdb。RDB 技术非常适合做备份,可以保存最近一个小时,一天,一个月的全部数据。保存
数据是在单独的进程中写文件,不影响 Redis 的正常使用。RDB 恢复数据时比其他 AOF 速度快。 2) 如何实现?
RDB 方式的数据持久化,仅需在 redis.conf 文件中配置即可,默认配置是启用的。
在配置文件 redis.conf 中搜索 SNAPSHOTTING, 查找在注释开始和结束之间的关于 RDB 的配置说明。配 SNAPSHOTTING 置地方有三处。
①:配置执行RDB 生成快照文件的时间策略。 对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个 key 改动”这一条件被满足时, 自动保存一次数据集。
配置格式:save save 900 1 save 300 10 save 60 10000
②:dbfilename:设置 RDB 的文件名,默认文件名为 dump.rdb
③:dir:指定RDB 文件的存储位置,默认是 ./ 当前目录
配置步骤: ①:查看 ps -ef | grep redis ,如果 redis 服务启动,先停止。 ②:修改 redis.conf 文件, 修改前先备份,执行 cp redis.conf bak_redis.conf
查看默认启用的 RDB 文件
③:编辑 redis.conf 增加save 配置,修改文件名等。vim redis.conf 修改的内容:
把原来的默认的dump.rdb 删除,修改 redis.conf 后,重新启动 redis ④:在 20 秒内容,修改三个 key 的值 ⑤:查看生成的 rdb 文件
3)总结 优点:由于存储的是数据快照文件,恢复数据很方便,也比较快缺点: 1) 会丢失最后一次快照以后更改的数据。如果你的应用能容忍一定数据的丢失,那么使用 rdb 是不错的选择;如果你不能容忍一定数据的丢失,使用 rdb 就不是一个很好的选择。 2) 由于需要经常操作磁盘,RDB 会分出一个子进程。如果你的redis 数据库很大的话,子进程占用比较多的时间,并且可能会影响Redis 暂停服务一段时间(millisecond 级别),如果你的数据库超级大并且你的服务器 CPU 比较弱,有可能是会达到一秒。
例 1: ①:停止运行的 redis , 备份要修改的 redis.conf ②:查看 redis 安装目录/src 下有无 .aof 文件。 默认是在 redis 的当前目录 ③:编辑 redis.conf 设 置 appendonly 为 yes 即 可 。 查看 appendfsync 的当前策略。 查看 appendfilname 的文件名称
④:在redis 客户端执行 写入命令
⑤ 查看aof 文件
总 结1)append-only 文件是另一个可以提供完全数据保障的方案; 2)AOF 文件会在操作过程中变得越来越大。比如,如果你做一百次加法计算,最后你只会在数据库里面得到最终的数值,但是在你的AOF 里面会存在 100 次记录,其中 99 条记录对最终的结果是无用的;但 Redis 支持在不影响服务的前提下在后台重构 AOF 文件, 让文件得以整理变小 3)可以同时使用这两种方式,redis 默认优先加载aof 文件(aof 数据最完整);
通过持久化功能,Redis 保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,但是由于数据是存储在一台服务器上的, 如果这台服务器出现故障,比如硬盘坏了,也会导致数据丢失。
为了避免单点故障,我们需要将数据复制多份部署在多台不同的服务器上,即使有一台服务器出现故障其他服务器依然可以继续提供服务。 这就要求当一台服务器上的数据更新后,自动将更新的数据同步到其他服务器上,那该怎么实现呢? Redis 的主从复制。
Redis 提供了复制(replication)功能来自动实现多台 redis 服务器的数据同步(每天 19 点 新闻联播,基本从 cctv1-8,各大卫视都会播放) 我们可以通过部署多台 redis,并在配置文件中指定这几台 redis 之间的主从关系,主负责写入数据,同时把写入的数据实时同步到从机器,这种模式叫做主从复制,即 master/slave,并且 redis 默认master 用于写,slave 用于读,向slave 写数据会导致错误
方式 1:修改配置文件,启动时,服务器读取配置文件,并自动成为指定服务器的从服务器,从而构成主从复制的关系 方 式 2 : ./redis-server --slaveof ,在启动 redis 时指定当前服务成为某个主 Redis 服务的从Slave
方式 1 的实现步骤: 模拟多Reids 服务器, 在一台已经安装 Redis 的机器上,运行多个Redis 应用模拟多个 Reids 服务器。一个 Master,两个 Slave.
新建三个Redis 的配置文件如果Redis 启动,先停止。 作为Master 的Redis 端口是 6380 作为Slaver 的Redis 端口分别是 6382 , 6384 从原有的 redis.conf 拷贝三份, 分别命名为 redis6380.conf, redis6382.conf , redis6384.conf
编辑 Master 配置文件编辑Master 的配置文件 redis6380.conf : 在空文件加入如下内容 include /usr/local/redis-3.2.9/redis.conf daemonize yes port 6380 pidfile /var/run/redis_6380.pid logfile 6380.log dbfilename dump6380.rdb
配置项说明: include : 包 含 原 来 的 配 置 文 件 内 容 。 /usr/local/redis-3.2.9/redis.conf 按照自己的目录设置。daemonize:yes 后台启动应用,相当于 ./redis-server & , &的作用。 port : 自定义的端口号
pidfile : 自定义的文件,表示当前程序的 pid ,进程 id。logfile:日志文件名 dbfilename:持久化的 rdb 文件名
编辑 Slave 配置文件编辑Slave 的配置文件redis6382.conf 和redis6384.conf: 在空文件加入如下内容 ①:redis6382.conf: include /usr/local/redis-3.2.9/redis.conf daemonize yes port 6382 pidfile /var/run/redis_6382.pid logfile 6382.log dbfilename dump6382.rdb slaveof 127.0.0.1 6380
配置项说明: slaveof : 表示当前 Redis 是谁的从。当前是 127.0.0.0 端口 6380 这个Master 的从。
②:redis6384.conf:
include /usr/local/redis-3.2.9/redis.conf daemonize yes port 6384 pidfile /var/run/redis_6384.pid logfile 6384.log dbfilename dump6384.rdb slaveof 127.0.0.1 6380 4) 启动服务器 Master/Slave 都启动
启动方式 ./redis-server 配置文件 启动 Redis,并查看启动进程
查看配置后的服务信息命令: ①: Redis 客户端使用指定端口连接Redis 服务器
./redis-cli -p 端 口 ②:查看服务器信息 info replication
登录到 Master:6380 查看当前服务信息 在客户端的Redis 内执行命令 info replication Master 服务的查看结果: 在新的Xshell 窗口分别登录到 6382 ,6384 查看信息 6384 也登录内容同 6382.
向Master 写入数据在 6380 执行 flushall 清除数据,避免干扰的测试数据。 生产环境避免使用。
在从Slave 读数据6382,6384 都可以读主 Master 的数据,不能写
Slave 写数据失败
当Master 服务出现故障,需手动将slave 中的一个提升为master, 剩下的slave 挂至新的 master 上(冷处理:机器挂掉了,再处理)
命令: ①:slaveof no one,将一台slave 服务器提升为 Master (提升某 slave 为master) ②:slaveof 127.0.0.1 6381 (将slave 挂至新的master 上)
执行步骤:
将 Master:6380 停止(模拟挂掉)
选择一个Slave 升到 Master,其它的 Slave 挂到新提升的 Master
将其他Slave 挂到新的 Master
在Slave 6384 上执行 现在的主从(Master/Slave)关系:Master 是 6382 , Slave 是6384 查看6382:
原来的服务器重新添加到主从结构中6380 的服务器修改后,从新工作,需要把它添加到现有的Master/Slave 中 先启动 6380 的 Redis 服务
连接到 6380 端口 当前服务挂到Master 上
查看新的 Master 信息在 6382 执行: 现在的Master/Slaver 关系是: Master: 6382 Slave: 6380 6384
进入客户端需指定端口:./redis-cli -p 6380 不配置启动默认都是主 master info replication 查看 redis 服务器所处角色
1、一个master 可以有多个slave 2、slave 下线,读请求的处理性能下降 3、master 下线,写请求无法执行 4、当 master 发生故障,需手动将其中一台 slave 使用 slaveof no one 命令提升为 master,其它 slave 执行 slaveof 命令指向这个新的master,从新的 master 处同步数据 5、主从复制模式的故障转移需要手动操作,要实现自动化处理,这就需要Sentinel 哨兵,实现故障自动转移
Sentinel 哨兵是 redis 官方提供的高可用方案,可以用它来监控多个 Redis 服务实例的运行情况。Redis Sentinel 是一个运行在特殊模式下的 Redis 服务器。Redis Sentinel 是在多个 Sentinel 进程环境下互相协作工作的。
Sentinel 系统有三个主要任务: ⚫ 监控:Sentinel 不断的检查主服务和从服务器是否按照预期正常工作。 ⚫ 提醒:被监控的 Redis 出现问题时,Sentinel 会通知管理员或其他应用程序。 ⚫ 自动故障转移:监控的主 Redis 不能正常工作,Sentinel 会开始进行故障迁移操作。将一个从服务器升级新的主服务器。 让其他从服务器挂到新的主服务器。同时向客户端提供新的主服务器地址。
Sentinel 配置
Sentinel 配置文件复制三份sentinel.conf文件:
Sentinel 系统默认 port 是 26379 。三个配置 port 分别设置为
26380 , 26382 , 26384 。三个文件分别命名: ⚫ sentinel26380.conf ⚫ sentinel26382.conf ⚫ sentinel26384.conf 执行复制命令 cp sentinel.conf xxx.conf
三份sentinel 配置文件修改:1、修改 port 26380、 port 26382、 port 26384 2、修改 sentinel monitor mymaster 127.0.0.1 6380 2 格 式 : sentinel monitor <Quorum 投票数>
Sentinel监控主(Master)Redis, Sentinel根据Master的配置自动发现Master的Slave,Sentinel默认端口号为26379 。
sentinel26380.conf
修改port2.修改监控的master 地址 sentinel26382.conf 修改port 26382 , master的port 6382 sentinel26384.conf 修改port 26384 , master的port 6382
启动主从(Master/Slave)Redis启动Reids 查看 Master 的配置信息 连接到 6382 端口 使用 info 命令查看 Master/Slave 4) 启动Sentinel
redis安装时make编译后就产生了redis-sentinel程序文件,可以在一个redis中运行多个sentinel进程。
启动一个运行在Sentinel模式下的Redis服务实例 ./redis-sentinel sentinel 配置文件
执行以下三条命令,将创建三个监视主服务器的Sentinel实例: ./redis-sentinel …/sentinel26380.conf ./redis-sentinel …/sentinel26382.conf ./redis-sentinel …/sentinel26384.conf
在XShell 开启三个窗口分别执行:
主Redis 不能工作让 Master 的Redis 停止服务, 执行 shutdown 先执行 info replication 确认 Master 的Redis ,再执行 shutdown
查看当前Redis 的进程情况
Sentinel 的起作用在 Master 执行 shutdown 后, 稍微等一会 Sentinel 要进行投票计算,从可用的Slave 选举新的Master。 查看Sentinel 日志,三个Sentinel 窗口的日志是一样的。
查看新的Master 查看原Slave 的变化
新的Redis 加入 Sentinel 系统,自动加入 Master重新启动 6382 查看 6384 的信息 测试数据:在Master 写入数据 在 6382 上读取数据,不能写入
监控1) Sentinel 会不断检查 Master 和Slave 是否正常 2) 如果Sentinel 挂了,就无法监控,所以需要多个哨兵,组成Sentinel 网络,一个健康的 Sentinel 至少有 3 个 Sentinel 应用。 彼此在独立的物理机器或虚拟机。 3) 监控同一个 Master 的Sentinel 会自动连接,组成一个分布式的 Sentinel 网络,互相通信并交换彼此关于被监控服务器的信息 4) 当一个 Sentinel 认为被监控的服务器已经下线时,它会向网络中的其它Sentinel 进行确认,判断该服务器是否真的已经下线 5) 如果下线的服务器为主服务器,那么 Sentinel 网络将对下线主服务器进行自动故障转移,通过将下线主服务器的某个从服务器提升为新的主服务器,并让其从服务器转移到新的主服务器下,以此来让系 统重新回到正常状态 6) 下线的旧主服务器重新上线,Sentinel 会让它成为从,挂到新的主服务器下。 9)总结 主从复制,解决了读请求的分担,从节点下线,会使得读请求能力有所下降,Master 下线,写请求无法执行
Sentinel 会在 Master 下线后自动执行故障转移操作,提升一台 Slave 为 Master,并让其它 Slave 成为新 Master 的Slave
(一) 设置密码 访问 Redis 默认是没有密码的,这样不安全,任意用户都可以访问。可以启用使用密码才能访问 Redis。 设置 Redis 的访问密码, 修改 redis.conf 中这行 requirepass 密码。密码要比较复杂,不容易破解,而且需要定期修改。因为 redis 速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行 150K 次的密码尝试,需要指定非常非常强大的密码来防止暴力破解。
开启访问密码设置修改redis.conf , 使用vim 命令。找到requirepass 行去掉注释, requirepass 空格后就是密码。 例 1:设置访问密码是 123456 ,这是练习使用,生产环境要设置复杂密码 修改redis.conf,文件 480 行左右。原始内容: 修改后: 查看修改结果:
访问有密码的 Redis如果Redis 已经启动,关闭后,重新启动。
访问有密码的 Redis 两种方式: ①:在连接到客户端后,使用命令 auth 密码 , 命令执行成功后, 可以正常使用 Redis
②:在连接客户端时使用 -a 密码。例如 ./redis-cli -h ip -p port -a password
启动Redis
使用 ① 访问 输入命令 auth 密码
使用 ② 方式 (二) 绑定 ip 修改 redis.conf 文件,把# bind 127.0.0.1 前面的注释#号去掉, 然后把 127.0.0.1 改成允许访问你redis 服务器的 ip 地址,表示只允许该 ip 进行访问。多个 ip 使用空格分隔。
例 如 bind 192.168.1.100 192.168.2.10 (三) 修改默认端口 修改 redis 的端口,这一点很重要,使用默认的端口很危险, redis.conf 中修改port 6379 将其修改为自己指定的端口(可随意),端口 1024 是保留给操作系统使用的。用户可以使用的范围是1024-65535
使用 -p 参数指定端口,例如:./redis-cli -p 新设置端口
使用Redis 官方推荐的 Jedis,在 java 应用中操作 Redis。Jedis 几乎涵盖了 Redis 的所有命令。操作 Redis 的命令在Jedis 中以方法的形式出现。jedis 完全兼容redis 2.8.x and 3.x.x ⚫ Jedis 源码:https://github.com/xetorthio/jedis ⚫ api 文档:http://xetorthio.github.io/jedis/ ⚫ 下载:http://search.maven.org/ ,搜索jedis
浏览器打开:http://search.maven.org/ ,搜索 jedis。在 Download 处,点击 jar 最新的版本 jedis-2.9.0
Jedis 对象并不是线程安全的,在多线程下使用同一个 Jedis 对象 的一个线程安全的连接池
浏览器打开:http://search.maven.org/ ,搜索 commons-pool2。
在 Download 处,点击 jar
点击“jar”
Java 应用使用 Jedis 准备 项目中加入jar: ⚫ jedis-2.9.0.jar ⚫ commons-pool2-2.4.2.jar
加入项目后如图:
使用Jedis 连接实例池。
使用连接池操作hash 数据类型