redis-教程

x33g5p2x  于2021-09-28 转载在 Redis  
字(10.5k)|赞(0)|评价(0)|浏览(419)

Redis 使用

1. redis 介绍

NoSQL

  • 分类

键值(Key-Value)存储数据库
这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果数据库管理员(DBA)只对部分值进行查询或更新的时候,Key/value就显得效率低下了。举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB。
列存储数据库
这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
文档型数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值,在处理网页等复杂数据时,文档型数据库比传统键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
图形(Graph)数据库
图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Graph。

  • 特点

对于NoSQL并没有一个明确的范围和定义,但是他们都普遍存在下面一些共同特征:
易扩展
NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。无形之间,在架构的层面上带来了可扩展的能力。
大数据量,高性能
NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。一般MySQL使用Query Cache。NoSQL的Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说性能就要高很多。
灵活的数据模型
NoSQL无须事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是——个噩梦。这点在大数据量的Web 2.0时代尤其明显。
高可用
NoSQL在不太影响性能的情况,就可以方便地实现高可用的架构。比如Cassandra、HBase模型,通过复制模型也能实现高可用。

  • 适用场景

NoSQL数据库在以下的这几种情况下比较适用:
1、数据模型比较简单;
2、需要灵活性更强的IT系统;
3、对数据库性能要求较高;
4、不需要高度的数据一致性;
5、对于给定key,比较容易映射复杂值的环境。

Redis

Redis安装

  • redis 安装环境
    redis 是 C 语言开发,建议在 linux 上运行,本教程使用 Centos7 作为安装环境。
    安装 redis 需要先从官网下载的源码进行编译,编译依赖 gcc 环境,如果没
    有 gcc 环境,需要安装 gcc:yum install gcc-c++。

等待…
期间问道: yes or no 你可以自己考虑。反正我都是yes。
看到下面的结果说明OK了

我们使用的 Redis 版本为 redis6.2.5 版本,首先可以从官网下载 Redis 压缩包:
网址:https://redis.io/download

下载后的文件:

将这个文件上传到Centos的 /usr/local下

接下来解压 Redis 压缩包:

进入解压后的目录进行编译和安装,编译使用命令 make,安装使用命令make install。
make
有如下的输出,说明make结束:

make install

完成后我们会在 /usr/loca/bin目录下看到如下redis命令:

linux中命令也是文件,你可以将这个命令文件拷贝到别的地方使用。

驱动redis:
redis-server
看到如下界面,说明redis服务启动成功

再打开一个连接界面,进入 /usr/loca/bin目录 使用名redis-cli连接redis服务器:

redis的启停

  • 前端模式启动
    直接运行 redis-server 将以前端模式启动,前端模式启动的缺点是占用终端,
    同时 ssh 命令窗口关闭则 redis-server 程序结束,所以不推荐使用此方法。
  • 后端模式启动
    修改 redis.conf 配置文件, 将 daemonize 设置 yes 以后即可以后端模式
    来启动 Redis。
    将redis解压的目录中的redis.conf文件拷贝到/usr/local/bin目录下:

修改配置: vi redis.conf

修改之后用当前修改后的配置文件来启动 Redis 服务器。

查看进程:

  • 启动多个 redis 进程
    启动多个 Redis 服务,一般采用定义多个对应的配置文件的方式来启动不同
    配置的 Redis 服务,同时需要分别修改每一个 Redis 服务器启动的端口号。这
    里我们启动两个 Redis 服务器,分别使用 6379 和 6380 端口。

首先我们创建两个目录。

在两个目录中定义 redis 的配置文件,这里我们将 redis 默认的配置文件拷贝过来,并修改对应的端口号,然后分别启动两个 Redis 服务。

修改redis6380中配置文件的端口为6380

分别在两个目录中启动redis:
查看进程:

使用客户端连接:

redis 的停止
要停止正在运行的 Redis 服务,可以采用 Linux 命令的方式直接杀掉 Redis服务的进程,也可以使用 Redis 客户端想服务器发送 shutdown 指令来关闭Redis 服务器。

Redis常用配置

  • bind配置

配置redis监听的网卡地址的。

比如:有一台双网卡的电脑。

其中网卡1是:192.168.12.131

网卡2:192.168.12.132

配置如下:

bind 192.168.12.132   #网卡2

所有通过网卡2链接当前服务器的客户端才能链接到reids服务。

如果希望redis监听所有网卡,将这个配置注释。

配置为127.0.0.1,任何其他客户端都无法访问,只能通过本机的客户端访问。

我们的做法是,直接注释

  • protected-mode

在redis5.0开始有的,默认是yes

当配置为yes的时候,redis是不允许其他的主机了来链接的。

我们将这个配置修改为no

PORT

time-out

客户端链接超时时。默认是0,就是永不超时。

  • databases

redis的默认数据库数量,默认是16个,索引从0~15。

  • daemonize

配置redis是否是守护进程。所谓守护进程就是说在后台运行,启动的时候,不会占用一个窗口。

默认配置为no。

我们常见的就是配置为yes。

Redis命令

向 Redis 服务器发送命令

redis-cli 连上 redis 服务后,可以在命令行向 Redis 服务器发送命令。

ping 命令
Redis 提供了 PING 命令来测试客户端与 Redis 的连接是否正常,如果连接正常会收到回复 PONG。

set/get 命令
使用 set 和 get 可以向 redis 设置数据、获取数据。

del 命令
del 命令用来删除指定 key 的内容。

keys命令
keys
命令用来查看当前 redis 数据库中存在的 key 的名称。

  • flushdb 命令
    flushdb 命令用来清空当前数据库中的所有数据。

  • flushall 命令 清空所有数据库的数据

Redis 多数据库

一个 Redis 数据库可以包括多个数据库,客户端可以指定连接某个 redis 实例的哪个数据库,就好比一个 mysql 中创建多个数据库,客户端连接时指定连接哪个数据库。一个 redis 实例默认提供 16 个数据库,这由启动的配置文件中指定,下标从 0 到 15,客户端默认连接第 0 号数据库,也可以通过 select 选择连接哪个数据库,不同数据库中的数据不能共享。

切换数据库:

需要注意的问题是,如果我们使用 flushall 命令清空某一个库中的数据时,
其他库中的数据也会被清空,因此,在我们不同的业务访问 Redis 服务器时应该
选择不同的 Redis 服务器,而不是同一个服务器内部的不同的数据库。

redis 的数据类型

String 类型

​ redis 中没有使用 C 语言的字符串表示,而是自定义一个数据结构叫 SDS(simple dynamic string)即简单动态字符串。redis 的字符串是二进制安全的,存入什么数据取出的还是什么数据。
String 类型的的常用命令有:
赋值命令
redis 中赋值操作使用 set 命令,语法 set key value。
如果希望一次性插入多条数据,可以使用mset命令,语法mset key1 value1
key2 value2 …

理论上字符串是不需要双引号的,但是如果字符串中间有空格,则要加上双引号。

案例: tips:所有的简单类型(java中的基本类型和String)都是字符串

取值命令
redis 中进行取值操作使用 get 命令,语法:get key。
需要注意的是,如果通过 get 命令获取数据时,给定的键不存在,则返回(nil),表示查询结果为空。
如果希望一次性从 redis 中获取多个键对应的数据的值,可以使用 mget 命令,语法:mget key1 key2 …
我们也可以使用 getset 命令,在获取对应键的数据的同时,为该键指定新的值。语法:getset key newValue

案例:

删除命令
在 Redis 中删除数据使用 del 命令,语法:del key。
如果需要直接清空该库中所有数据,可以使用 flushdb 命令。
如果要清空所有库中的所有数据使用 flushall 命令。

案例:略

数值递增
当存储的字符串是整数时,Redis 提供了一个实用的命令 incr,其作用是让当前键值递增,并返回递增后的值。语法:incr key。

incr 只能操作整数类型的。 如果字符串不是整数形式,就会报错。

使用incr的时候,如果key不存在,会自动添加这个key,并且默认从0开始。

以上的自增表示每次加 1,如果需要按照指定的数据来进行增长,可以使用incrby 命令,语法:incrby key increment。

数值递减
当需要对数据进行递减操作时,使用 decr 命令,语法:decr key。
如果希望递减指定的数值,可以使用 decrby,语法:decrby key decrement。

decr 的一些特征和incr一致。  如果key不存在则默认从0开始递减。

追加数据
在 Redis 中可以使用 append 命令向指定数据的末尾追加内容,语法:append key value。

获取长度
使用 strlen 命令可以返回指定键对应的值的长度,如果键不存在则返回 0。
语法:strlen key。

hash 类型

hash 叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。

hash类型可以简单理解为java中的map。

hash 类型的的常用命令有:
赋值命令
向 hash 中插入获设置数据没使用 hset 命令,语法:hset key field value。
如果希望从 redis 中一次性设置多个字段的值,可以使用 hmset,语法:
hmset key field1 value1 field2 value2 …

案例:

取值命令
从 hash 中获取数据使用 hget 命令,语法:hget key field。
使用 hmget 可以一次性获取多个字段的值。语法:hmget key field1 field2field3 …
可以使用 hgetall 命令,或者指定键的所有字段和字段的值。语法:hgetall key。
使用 HKEYS 和 HVALS 命令可以分别用来获取指定键的所有键和所有值。

判断字段是否存在
判断字段是否存在使用 HEXISTS 命令,如果存在则返回 1,如果不存在则返回 0 ,语法:HEXISTS key field

获取字段数量
获取字段数量使用 HLEN 命令,如果键不存在则返回 0,语法 HLEN key。

删除命令
要删除一个或多个字段,使用 hdel 命令,语法:HDEL key field [field …]。

增加数字
如果 hash 中的字段存储的值为数值类型,可以进行自增操作。语法:
HINCRBY key field increment

如果要减就加负数。

list 类型

列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为 0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的 10 条记录也是极快的。

和java中的list相似,有序可重复。

list 类型的的常用命令有:
添加数据
Redis 列表采用双向链表实现,因此在插入数据时可以从两端分别操作,向列表左边增加元素使用 lpush 命令,向列表右边增加元素使用 rpush 命令。

上面的列表是如何排列的???

查看列表
LRANGE 命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回 start、stop 之间的所有元素(包含两端的元素),索引从 0 开始。索引可以是负数,如:“-1”代表最后边的一个元素。列表的左侧插入数据,在列表中数据以倒叙存放,从列表的右侧插入数据则是正序存放。

语法:lrange listName start end

一般情况下: end 为-1 表示获取到列表的末尾。

tips:只有lrang,没有rrange

查看所有的:

查看部分数据:

tips: 这里的范围是一个闭区间。3和6都会获取。

获取数据
在列表中可以使用 lpop 和 rpop 分别列表的左侧和右侧弹出一个数据,该数据会首先返回,然后再从原列表中删除。

获取列表中元素的个数
使用 LLEN 命令可以获取列表中元素的个数。范例:LLEN key

删除列表中指定的值
LREM 命令会删除列表中前 count 个值为 value 的元素,返回实际删除的元素个数。根据 count 值的不同,该命令的执行方式会有所不同:
 当 count>0 时, LREM 会从列表左边开始删除。
 当 count<0 时, LREM 会从列表后边开始删除。
 当 count=0 时, LREM 删除所有值为 value 的元素。

从左边删除两个a:

从右边删除两个b:

删除所有的a:

获得/设置指定索引的元素值
获得或者设置指定索引的元素值分别使用 lindex 和 lset 命令。

只保留列表指定片段
List中使用ltrim命令对列表中的数据进行截取操作,只保留指定数据片段。
语法:ltrim key start stop。

tips: 这里的start和stop也是闭区间

向列表中插入元素
向列表中指定位置插入元素可以使用 linsert 命令,语法:LINSERT key BEFORE|AFTER pivot value。

将元素从一个列表转移到另一个列表中
使用 RPOPLPUSH 命令可以将元素从一个列表转移到另一个列表中。语法:
RPOPLPUSH source destination

set 类型

集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型的 Redis 内部是使用值为空的散列表实现,所有这些操作的时间复杂度都为 0(1)。 Redis 还提供了多个集合之间的交集、并集、差集的运算。

简单理解为java中的set,元素是无序不重复的。 尝尝用来去重。

set 类型的的常用命令有:
增加/删除元素
集合中添加数据使用 sadd 命令,语法 sadd key member [member…].

tips:重复元素是无法添加的。

获得集合中的所有元素
获取集合中所有元素使用 SMEMBERS 命令,语法:SMEMBERS key

由于没有顺序,所以每次都是获取全部元素。

集合的交集运算
属于 A 并且也属于 B 的元素构成的集合,使用命令 SINTER,语法:SINTER key [key …]

集合的并集运算
属于 A 并且或者属于 B 的元素构成的集合,使用命令 SUNION,语法:
SUNION key [key …]

集合的差集运算

A集合减去B集合,则只留A集合中有,B集合中没有的元素。使用命令sdiff 语法: SDIFF KEY1 KEY2

获得集合中元素的个数
获得集合中元素的个数,使用 SCARD 命令,如果集合不存在则返回 0,语法:SCARD key

从集合中弹出一个元素
从集合中弹出一个元素使用 spop 命令,语法:spop key

sorted set 类型

在集合类型的基础上有序集合类型为集合中的每个元素都关联一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。
在某些方面有序集合和列表类型有些相似。
1、二者都是有序的。
2、二者都可以获得某一范围的元素。
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。
sorted set 类型的的常用命令有:
增加元素
向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。语法:ZADD key score member [score member …]

获得排名在某个范围的元素列表
获得排名在某个范围的元素列表使用 zrange 命令,语法:ZRANGE key start stop [WITHSCORES]
如果要进行降序排列,我们使用命令ZREVRANGE。

查询的同时显示分数

将序排序查询

删除元素
移除有序集 key 中的一个或多个成员使用命令 ZREM,不存在的成员将被忽略。语法:ZREM key member [member …]

获得指定分数范围的元素
获 得 指 定 分 数 范 围 的 元 素 使 用 ZRANGEBYSCORE 命 令 , 语 法 :ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

按照分数范围获取

在分数范围内再取指定的个数:

增加某个元素的分数,返回值是更改后的分数
增加某个元素的分数,返回值是更改后的分数,使用命令 ZINCRBY,语法:ZINCRBY key increment member

获得集合中元素的数量
获取集合中元素的数量使用 ZCARD 命令,语法:ZCARD key。

获得指定分数范围内的元素个数
获得指定分数范围内的元素个数使用命令 zcount,语法:ZCOUNT key min max。

按照排名范围删除元素
按 照 排 名 范 围 删 除 元 素 使 用 命 令 ZREMRANGEBYRANK ,

语 法 :ZREMRANGEBYRANK key start stop

按照分数范围删除元素
按 照 分数 范围 删除 元素使用 命令 ZREMRANGEBYSCORE ,语法:
ZREMRANGEBYSCORE key start stop

获取元素的排名
获取元素的排名使用 zrank 命令,语法:ZRANK key member
如果要使用倒序排名使用命令 ZREVRANK。

redis 的其他命令

redis中的key可以设置存活时间,过了时间会自动消亡。在不设置存活时间的情况下,默认是永久存在的。
设置 key 的生存时间
Redis 在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。

EXPIRE key seconds  设置 key 的生存时间(单位:秒)key 在多少秒后会自动删除
TTL key 查看 key 生于的生存时间
PERSIST key  清除生存时间
PEXPIRE key milliseconds  生存时间设置单位为:毫秒

TTL用来查看key的存活时间, 默认是永久的,返回-1

EXPIRE key seconds设置key的存活时间,单位是秒

当key过期的时候,就会返回-2。表示key已经不存在了。

不能试图设置存活时间为-1或者-2.

可以通过PERSIST key清除key的存活时间。

tips:再实际的应用中都是用这种方式来做标记的。 比如抢购倒计时,分布式锁,模拟session。
返回满足给定 pattern 的所有 key
Redis 中可以使用 pattern 来获取键的名称。

重命名 key
重命名 key 使用命令 rename,语法:rename name newName

返回值的类型
使用 type 命令可以返回指定键的值的类型,语法:type key。

返回当前数据库中 key 的数目
返回当前数据库中 key 的数目使用 dbsize 命令。

redis 的持久化

Redis 的高性能是由于其将所有数据都存储在了内存中,为了使 Redis 在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。
Redis 支持两种方式的持久化,一种是 RDB 方式,一种是 AOF 方式。
可以单独使用其中一种或将二者结合使用。

RDB 持久化

RDB 方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时 Redis 会自动将内存中的数据进行快照并持久化到硬盘。(以数据文件的形式存储数据。)
RDB 是 Redis 默认采用的持久化方式,在 redis.conf 配置文件中默认有此下配置:

# 默认的存储数据的数据文件名称
# The filename where to dump the DB
dbfilename dump.rdb
# 存储数据的文件所在的位置 默认是当前路径,在哪里启动的服务,就在哪里存储dump.rdb文件
# Note that you must specify a directory here, not a file name.
dir ./

# 持久化策略
# Unless specified otherwise, by default Redis will save the DB:
# * After 3600 seconds (an hour) if at least 1 key changed
# * After 300 seconds (5 minutes) if at least 100 keys changed
# * After 60 seconds if at least 10000 keys changed
#
# You can set these explicitly by uncommenting the three following lines.
#
 save 3600 1
 save 300 100
 save 60 10000

save 开头的一行就是持久化配置,可以配置多个条件(每行配置一个条件),每个条件之间是“或”的关系,“save 3600 1”表示 60 分钟(3600 秒钟)内至少 1 个键被更改则进行快照,“save 300 10”表示 5 分钟(300 秒)内至少 100个键被更改则进行快照。
Redis 启动后会读取 RDB 快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将记录一千万个字符串类型键、大小为 1GB 的快照文件载入到内存中需要花费 20~30 秒钟。
如果开启了 RDB,Redis 默认会在启动当前服务的目录自动创建数据文件。通过 RDB 方式实现持久化,一旦Redis 异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。如果数据很重要以至于无法承受任何损失,则可以考虑使用 AOF 方式进行持久化。

测试: 设置一个key,使用 kill -9 干掉redis进程。

tips:调用save命令或者正常关闭redis,都会产生新的快照。

AOF的持久化

默认情况下 Redis 没有开启 AOF(append only file)方式的持久化,可以通过 appendonly 参数开启:appendonly yes
开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将该命令写入硬盘中的 AOF 文件。AOF 文件的保存位置和 RDB 文件的位置相同,都是通过 dir 参数设置的,默认的文件名是 appendonly.aof,可以通过
appendfilename 参数修改:appendfilename appendonly.aof

开启之后,我们会发现在对应的位置缠上一个appendonly.aof文件:

这个文件是用来记录所有的对key的增删改操作的命令的。当我们重启redis的时候,会默认将这些命令全部执行一边。

RDB模式可能会丢失数据,AOF不会丢失。

AOF文件过大,RDB文件相对较小。

所以redis往往使用来做缓存的,持久化存储还是建议使用关系型数据库。

redis 的主从复制

随着需求发展,出现了三高问题:高性能,高可用,高并发

什么是主从复制

持久化保证了即使 redis 服务重启也会丢失数据,因为 redis 服务重启后会将硬盘上持久化的数据恢复到内存中,但是当 redis 服务器的硬盘损坏了可能会导致数据丢失,如果通过 redis 的主从复制机制就可以避免这种单点故障。

说明:
 主 redis 中的数据有两个副本(replication)即从 redis1 和从 redis2,即使一台 redis
服务器宕机其它两台 redis 服务也可以继续提供服务。
 主 redis 中的数据和从 redis 上的数据保持实时同步,当主 redis 写入数据时通过主从
复制机制会复制到两个从 redis 服务上。
 只有一个主 redis,可以有多个从 redis。
 主从复制不会阻塞 master,在同步数据时,master 可以继续处理 client 请求

主从复制实现
在 Redis 从服务器上添加其对应的主服务器的信息,修改从 redis 服务器上
的 redis.conf 文件,添加 slaveof 主 redis 服务器的 ip 和端口号。

启动主从服务器之后即完成了对 Redis 主从复制的配置。

我们的计划:

在133上启动一个主服务器,在132上启动两个从服务器

在133准备一个干净的redis。 在132上准备两个redis服务,并且清理干净数据。

修改132上的两个配置文件的配置,配置master的IP和端口:

启动主服务器,再启动两个从服务器。
主服务器一定要开放端口。

主服务器要确保可以远程访问。

相关文章