---
cid: 213
title: redis学习笔记(1)
slug: 213
date: 2020/02/09 16:19:00
updated: 2020/02/15 14:02:28
status: publish
author: harumonia
categories:
  - 源流清泉
  - DataBase
tags:
  - redis
noThumbInfoStyle: default
outdatedNotice: yes
reprint: standard
thumbChoice: default
thumbStyle: default
hidden: false
---

# 1. 基础

## 1.1 常识

Redis 是用 C 语言开发的一个开源的高性能键值对（key-value）数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求，目前为止 Redis 支持的键值数据类型如下：

- 字符串类型
- 散列类型
- 列表类型
- 集合类型
- 有序集合类型

<!-- more -->

## 1.2 特性

- 速度快(数据保存在内存中)
- 持久化(Redis 所有数据保持在内存中,对数据的更新将异步地保存到磁盘上)
- 多种数据结构
- 多语言客户端
- 功能丰富
- 简单(源代码 23000lines)
- 主从复制(主服务器同步到从服务器)
- 高可用\分布式

## 1.3 安装

### 文件说明

| 文件             | 功能               |
| ---------------- | ------------------ |
| redis-server     | Redis 服务器       |
| redis-cli        | Redis 命令行客户端 |
| redis-benchmark  | Redis 性能测试     |
| redis-check-aof  | AOF 文件修复工具   |
| redis-check-dump | RDB 文件检查工具   |
| redis-sentinel   | Sentinel 服务器    |

### 启动

redis-server 最简启动
redis-server --port 6380 动态参数启动
redis-server configPath 配置文件启动

### 验证

```bash
netstat -antp | grep redis
or
reids-cli -h ip -p port ping
```

# 2 API

## 2.1 基础命令

### 2.1.1 字符串

String 数据结构是简单的 **key-value** 类型，value 其实不仅是 String，也可以是数字，是包含很多种类型的特殊类型，并且是二进制安全的。

> 比如序列化的对象进行存储，比如一张图片进行二进制存储，比如一个简单的字符串,数值等等。

#### 使用场景

- 缓存
- 计数器

#### 命令

- 设值：set name zhangsan (说明：多次设置 name 会覆盖)
  命令：

  - setnx key1 value1： (not exist) 如果 key1 不存在，则设值 并返回 1。如果 key1 存在，则不设值并返回 0；

  - setex key1 10 lx :(expired) 设置 key1 的值为 lx，过期时间为 10 秒，10 秒后 key1 清除（key 也清除）

  - setrange string range value 替换字符串

- 取值: get key
- 删值：del keys
- 批量写：mset k1 v1 k2 v2 ... 一次性写入多个值
- 批量读：mget k1 k2 k3
- 一次性设值和读取（返回旧值，写上新值）:getset name lx
- 数值类型自增减：incr key，decr key 注意这些 key 对应的必须是数字类型字符串,否则会出错,自增或者自减 1
- 自增或自减指定长度 incrby key increment，decrby key increment 对应的 key 自增或者自减 increment 值
- 字符串尾部拼接：append key value 向 key 对应的字符串尾部追加 value
- 字符串长度：strlen key

#### 命令演示

![image-20200202201918881](http://typora-zxj.oss-cn-beijing.aliyuncs.com/typora/20200209170529-877062.png)

### 2.1.2 哈希

Hash 类型是 String 类型的 field 和 value 的映射表，或者说是一个 _String 集合_ 。

它特别适合 **存储对象** ，相比较而言，将一个对象类型存储在 Hash 类型要存储在 String 类型里占用更少的内存空间，并方整个对象的存取。

#### 命令1

- 设值：hset hashname field value（hset 是设值命令，hashname 是集合名字，field 是字段名，value 是值）
- 取值：hget hashname field
- 批量设置：hmset hashname field1 value1 field2 value2 ….
- 批量取值：hmget hashname field1 field2 ...
- hsetnx key field value：和 setnx 大同小异
- HINCRBY key field increment：指定字段增加指定值
- hexists key field：指定 key 中是否存在指定 field，如果存在返回 1，不存在返回 0
- hdel key field 删除指定 key 的 hash 的 field
- hlen：返回 hash 集合里的所有的键数量(size)
- hkeys key：返回 hash 里所有的 field
- hvals key：返回 hash 的所有 field 对应的 value
- hgetall key：返回 hash 里所有的 field 和 value

#### 命令演示1

![image-20200202204233903](http://typora-zxj.oss-cn-beijing.aliyuncs.com/typora/20200209170533-752821.png)

### 2.1.3 列表

List 类型是一个链表结构的集合，其主要功能有 push、pop、获取元素等。

更详细的说，List 类型是一个双端链表的节后，我们可以通过相关的操作进行集合的头部或者尾部添加和删除元素，List 的设计非常简单精巧，即可以作为栈，又可以作为队列，满足绝大多数的需求。

#### 命令2

- lpush key1 value1 value2...：从头部加入元素（栈，先进后出）

- rpush key1 value1 value2 ...：从尾部加入元素（队列，先进先出）

- linsert key BEFORE|AFTER pivot value
  该命令首先会在列表中从左到右查找值为 pivot 的元素，然后根据第二个参数是 BEFORE 还是 AFTER 来决定将 value 插入到该元素的前面还是后面

- lrange key start stop:获取指定索引内的所有元素,只可从左到右 0 -1 代表所有

- lset key index value：将 key 集合中 index 下表的元素替换掉

- lrem key count value

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

- ltrim key start stop：保留指定 key 的值范围内的数据, 其他数据会删掉, 和 lrange 一样的参数范围

- lpop key：从 list 的头部删除元素，并返回删除元素。

- rpop key：从 list 的尾部删除元素，并返回删除元素

- rpoplpush list1 list2：从 list1 尾部删除元素，并将被移除的元素添加到 list2 的头部，返回被移除的元素，可以实现 MQ

- llen key：返回元素个数

- lindex key index：返回名称为 key 的 list 中 index 位置的元素

#### 命令演示2

![image-20200202212137182](http://typora-zxj.oss-cn-beijing.aliyuncs.com/typora/20200209170632-878532.png)

### 2.1.4 集合

set 集合是 string 类型的无序集合，set 是通过 hashtable 实现的，对集合我们可以取交集、并集、差集

#### 命令3

- SADD key member [member ...]：向名称为 key 的 set 中添加元素，set 集合不允许重复元素。
- SMEMBERS key：查看 set 集合中的元素。
- SREM key member [member ...]：删除 set 集合的元素
- SPOP key：随机删除指定 set 中的一个内容并将删除的内容返回
- SDIFF key [key ...]：差集运算,返回在第一个 set 中存在,第二个 set 中不存在的内容
- sdiffstore set4 set2 set3 将 set2 set3 不同元素的比较结果保存到 set4 中
- SINTER key [key ...]：取交集,集合重复的数据
- sinterstore：set3 set1 set2 取交集后保存到 set3
- SUNION key [key ...]:取并集,因为是 set 所以相同部分只会取一次
- sunionstore set3 set1 set2：取并集后保存到 set1
- smove set1 set2：从一个 set 集合移动到另一个 set 集合里
- SCARD key：查看集合里的元素个数
- SISMEMBER key member：判断某个元素是否为集合中的元素，是，返回 1。不是，返回 0。
- srandmember key：随机返回一个元素

#### 命令演示3

![image-20200202212759047](http://typora-zxj.oss-cn-beijing.aliyuncs.com/typora/20200209170833-579770.png)

### 2.1.5 有序集合

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

有序集合的成员是唯一的,但分数(score)却 **可以重复** 。

集合是通过哈希表实现的，所以添加，删除，查找的复杂度都是 O(1)。 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储 40 多亿个成员)。

#### 命令4

- ZADD key score member [score member ...]： score 是分, member 是内容, score 必须是数字,向有序集合中添加一个元素，该元素如果存在则更新顺序，如果分值相同元素不同会同时存在两个元素。
- ZSCORE key member 获取指定 key 中指定内容的分数
- ZREM key member [member ...] ：删除 zset 名称 key 中的 member 元素
- ZRANGE key start stop [WITHSCORES] 获得排名在某个范围的元素列表,照元素分数从大到小的顺序返回索引从 start 到 stop 之间的所有元素（包含两端的元素）
  - [WITHSCORES] 获得排名在某个范围的元素列表,照元素分数从小到大的顺序返回索引从 start 到 stop 之间的所有元素（包含两端的元素）
  - [WITHSCORES]为可选项,代表是否在结果中显示分数
- ZRANK key member 返回有序集合中指定成员的索引（从小到大排序）
- ZREVRANK key member 返回有序集合中指定成员的排名，有序集成员按分数值递减(从大到小)排序
- ZCARD key 返回集合里所有元素的个数
- ZCOUNT key min max 返回集合中 score 在给定区间中的数量
- zincrby key increment member： 有序集合中对指定成员的分数加上增量 increment
- zrangebyscore key min max [WITHSCORES] [LIMIT offset count] ：通过分数返回有序集合指定区间内的成员
  - min max 代表分数范围
  - offset 代表偏移量,
  - count 代表获取多少个,类似于数据库
- zremrangebyrank key start stop ：移除有序集合中给定的排名区间的所有成员
- zremrangebyscore key min max：移除有序集合中给定的分数区间的所有成员
- ZINCRBY key increment member ： 增加 memeber 元素的分数 increment，返回值是更改后的分数

### 2.2 高级命令

### 2.2.1 常用命令

- keys : 返回满足的所有键 ,可以模糊匹配 比如 keys abc_ 代表 abc 开头的 key

- exists key ：是否存在指定的 key，存在返回 1，不存在返回 0

- expire key second：设置某个 key 的过期时间 时间为秒

- del key:删除某个 key

- ttl key：查看剩余时间,当 key 不存在时，返回 -2;存在但没有设置剩余生存时间时，返回 -1,否则，以秒为单位，返回 key 的剩余生存时间。

- persist key：取消过去时间

- PEXPIRE key milliseconds 修改 key 的过期时间为毫秒

- select : 选择数据库 数据库为 0-15（默认一共 16 个数据库）

  ps.设计成多个数据库实际上是为了数据库安全和备份

- move key dbindex ： 将当前数据中的 key 转移到其他数据库

- randomkey：随机返回一个 key

- rename key key2：重命名 key

- echo：打印命令

- dbsize：查看数据库的 key 数量

- info：查看数据库信息

- config get \* 实时传储收到的请求，返回相关的配置

- flushdb ：清空当前数据库

- flushall ：清空所有数据库

### 2.2.2 Redis 事务

Redis 事务可以一次执行多个命令， 并且带有以下两个重要的保证：

```plain_text
事务是一个单独的隔离操作：
事务中的所有命令都会序列化、按顺序地执行。
事务在执行的过程中，不会被其他客户端发送来的命令请求所打断。
事务是一个原子操作：
事务中的命令要么全部被执行，要么全部都不执行
```

一个事务从开始到执行会经历以下三个阶段：

- 开始事务
- 命令入队
- 执行事务

#### 常用命令

- MULTI 开启事务
- EXEC 执行事务
- DISCARD 取消事务
- WATCH key 监听某个 key 的值是否发生变化,如果发生变化, watch 之后的操作会失败

#### 命令演示5

![image-20200202225636915](http://typora-zxj.oss-cn-beijing.aliyuncs.com/typora/20200209170908-801420.png)

### 2.2.3 Redis 数据备份与恢复

#### 数据备份

```plain_text
Redis SAVE 命令用于创建当前数据库的备份。
```

#### 恢复数据

```plain_text
如果需要恢复数据，只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。
```

### 2.2.4 Redis 安全

因为 redis 速度相当快，所以一台比较好的服务器下，一个外部用户在一秒内可以进行 15W 次密码尝试，这意味着你需要设定非常强大的密码来防止暴力破解

可以通过 redis 的配置文件设置密码参数，这样客户端连接到 redis 服务就需要密码验证，这样可以让你的 redis 服务更安全

```bash
vim /usr/local/redis/conf/redis.conf
编辑配置文件
 修改：#reqirepass foobared
 为： reqirepass  redis(你的密码)

pkill redis-server   关闭redis-server
./bin/redis-server ./conf/redis.conf 启动redis
./bin/redis-cli   打开客户端
```
