redis基础,入门到进阶

redis基础及搭建

redis环境搭建

传输redis压缩包

通过远程登陆把redist.tar.gz压缩包上传到服务器的opt文件夹中

安装c语言编译环境

测试系统是否已经安装gcc指令gcc --version

运行命令yum install gcc安装gcc

解压redis压缩包

进入opt文件夹执行命令tar -zxvf redis-7.0.4.tar.gz

编译

进入redis-7.0.4.tar.gz文件夹中执行make命令

安装

在redis-7.0.4文件夹中执行make install进行安装 默认安装在usr/local/bin目录下

启动

进入usr/local/bin目录下执行redis-server启动redis服务

以守护进程模式启动服务:

  • 把opt/redis-7.0.4文件夹中的redis.conf复制到usr/local/etc文件夹中
  • 修改redis.conf文件中的daemonize值 改为yes 并把注释去掉
  • 在usr/loacl/bin目录下执行redis-server ../etc/redis.conf

小知识

后台运行redis

把redis.conf中的dzemonize改为yes

保护模式

redis默认在不设密码的状态下是开启protected-mode的

安全

设置密码

可以通过指令config get requirepass指令查看是否设置了密码验证

客户端连接上后执行config set requirepass rootroot即为设置的密码 此方法设置的密码服务重启后失效 也可以通过修改redis.conf文件中的requirepass设置密码(默认注释掉的)

设置密码后通过指令AUTH <password>进行密码验证

redis性能测试

指令格式redis-benchmark [option] [option value] 注意该命令实在redis目录下执行 而不是客户端内部指令

redis性能测试可选参数

选项描述默认值
-h指定服务器主机名127.0.0.1
-p指定服务器端口6379
-s指定服务器 socket
-c指定并发连接数50
-n指定请求数10000
-d以字节的形式指定 SET/GET 值的数据大小2
-k1=keep alive 0=reconnect1
-rSET/GET/INCR 使用随机 key, SADD 使用随机值
-P通过管道传输 请求1
-q强制退出 redis。仅显示 query/sec 值
–csv以 CSV 格式输出
-l(L 的小写字母)生成循环,永久执行测试
-t仅运行以逗号分隔的测试命令列表。
-I(i的大写字母)Idle 模式。仅打开 N 个 idle 连接并等待。

redis客户端连接

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

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

最大连接数

可以通过修改redis.conf文件的maxclients值

也可以通过启动服务时指令redis-sever --maxclients 10000设置

可以通过客户端内部指令config get maxclients查看设置客户端连接数最大值

客户端命令

命令描述
CLIENT LIST返回连接到 redis 服务的客户端列表
CLIENT SETNAME设置当前连接的名称
CLIENT GETNAME获取通过 CLIENT SETNAME 命令设置的服务名称
CLIENT PAUSE挂起客户端连接,指定挂起的时间以毫秒计
CLIENT KILL关闭客户端连接

通用

keys *查询所有的key

exists <key>查看该key是否存在

type <key>查看key的类型

del <key>删除key

unlink <key>异步删除key

expire <key> <time duriction>为key设置一个过期时间(秒)

ttl <key>查看剩余过期时间

select <db>切换数据库

dbsize返回数据库key数量

flushdb删除数据库中所有内容

flushall删除所有数据库

string字符串

set <key> <value>设置k_v

get <key>获取v

append <key><value>在key对应的值中追加value

strlen <key>返回key对应value的长度

setnx <key> <value>设置k_v,如果库中已经存在key,返回0

incr <key>key对应的值加一

decr <key>key对应的值减一

incrby <key> <num>key对应的值加num

decrby <key><num>key对应的值减num

mset <key1><value1> <key2><value2>...设置多k_v

mget <key1><key2>...获取多k_v

msetnx <key1><value1> <key2><value2>...设置多k_v,只要库中有任意一个key存在,就设置失败

getrange <key> start end获取key对应value中索引start至end的字符

setrange <key><offset><value>添加value在key的值域中offset位置

setex <key> <timeduriction><value>设置有寿命的k_v 单位秒

getset <key><value>获取key的值并用新值替换旧值

watch <key>...监视key的变化

unwatch 取消监视

list 列表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-obN9Cngq-1662040787618)(image-20220801164010100.png)]

单键多值,底层双链表实现

lpush <key> <value1><value2>...设置列表

lpop <key>取值

lrange <key> start end取索引在start和end之间的值

rpoplpush <key1><key2>在key1的右边取值放入到key2的左边

lindex <key><index>取指定索引的值

llen <key>返回链表长度

linsert <key> before/after <value> <newvalue>在value的前面/后面插入新值

lrem <key> <num> 从链表左边删除num个值

lset <key> <index> <value>给key的链表中索引为index换新值

set 无序集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ovsyg2sQ-1662040787619)(image-20220801163942083.png)]

string类型的无序集合,底层是一个hash表实现

sadd <key><value1><value1>...设置集合

smembers <key>返回集合中的元素

sismembers <key><value>判断是否为集合中的元素

scard <key>返回元素个数

srem <key><v1><v2>...删除

spop <key>随机突出一个元素

srandmembers <key> <num>随机返回num个元素 不删

smove <souce><destination><member>把source中的member移动到destination中

sinter <key1><key2>返回交集

sunion <key1><key2>返回并集

sdiff <key1><key2>返回差集,包含key1不包含key2

hash

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LQgKDNL6-1662040787620)(image-20220801162539105.png)]

hset <key><field><value>设置字段和值

hget <key><field>获取某字段值

hexists <key><field>判断某字是否存在

hkeys <key>获取所有的字段名

hvals <key>获取所有的字段值

hincrby <key><field><num>为field字段加num

hsetnx <key><field><value>为field字段设置值,如果存在则设置失败

hmset <key><field1><value1><field2><value2>...批量添加

Zset有序集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Qa98xO1-1662040787620)(image-20220801163829420.png)]

每个元素带有一个分数,根据分数对元素进行升序排序

zadd <key><score1><value1><score2><value2>...

zrange <key><start><end>[withscores]返回下表在start和end之间的有序集,可以带上每个元素的分数

zrangebyscore <key> min max [withscores][limit offset count]返回分数在min和max之间对应元素组成的集合,可以和分数一并返回 升序排序

zrangebyscore <key> max min [withscore][limit offset count]同上,降序排序

zrem <key><value>删除该集合中指定元素

zcount <key>min max统计该集合中分数在min和max区间内元素数量

zrank <key><value>返回该元素在集合中排名(从0开始)

zincrby <key><increment><value>为指定元素value的分数加increment

redis6的新数据类型

bitmaps

指令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUTYJ4kB-1662040787621)(image-20220801173034958.png)]

setbit<key><offset><value>设置Bitmaps中某个偏移量的值(0或1)

getbit<key><offset>获取bitmaps中某个偏移量的值

bitcount <key>[start end [BYTE|BIT]]返回字符串中从start到end字节比特值位1的数量

bitcount<key>[start end]统计字符串被设置为1的bit数 指定额外的参数start或end可以让计数只在特定的位上进行

bitop and/or/not/xor <destkey>[key...]bitop是一个复合操作 and交集 or并集 not非 xor异或 将结果保存在destkey中

实例:某个用户是否访问过网站,将访问过的标记为1,没有访问过的标记为0,偏移量标记为用户id

  • 很多用户id以一定数字开头,如果以bitmaps和用户id对应会造成一定浪费,通常做法是用户id减去这个值。

  • 在初始化bitmaps时,如果偏移量较大,那么初始化过程会比较慢,可能会造成redis阻塞

HypeLoglog

pfadd <key><value1><value2>...自动去重

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JVNT6Up9-1662040787621)(image-20220801180330373.png)]

pfcount <key>统计集合中基数的数量

pfmerge <key> <key2><key3>把key2和key3合并为key

Geospatial 地图

geoadd <key><longitude><latitude><member>...添加地理位置(经度,纬度,名称)

geopos <key><member>[member...]获取指定地区的坐标值

geodist <key><member1><member2>[m|km|ft|mi]获取两个位置之间的直线距离

georadius <key><longitude><latitude>radius m|km|ft|mi以给定的经纬度为中心,找出给定 半径范围内的地区

  • 注意:两极无法直接添加
  • 有效经度从-180到180,纬度从-85.05112878到85.05112878 超出范围返回一个错误
  • 单位默认为 m米 km千米 mi英里 ft英尺

redis的事务操作

multi开始组合命令

discard放弃命令组队

exec执行命令

watch <key>...监视一个或多个key,如果事务开始前这些key的值发生变化,那么这些事务就会被打断

unwatch <key>...取消监视这些key的值

注意

如果在组队时格式出现错误,执行时组内命令都不会执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kWbaHIrg-1662040787622)(image-20220802180729201.png)]

如果在组队时没有出错,在执行时出错,则出错的那条命令执行失败,其他的命令正常执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Gt4uK4h-1662040787622)(image-20220802181147274.png)]

乐观锁

顾名思义,就是每次拿数据时认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下此期间别人有没有更新这个数据,可以使用版本号的机制。乐观锁适用于多读的应用场景,这样可以提高吞吐量。redis就是通过这种check-and-set机制实现事务的。

悲观锁

对于操作上锁,影响效率。

redis事务特性

  • 隔离操作:事务中所有命令都会顺序的执行,不会被其他客户端所打断

  • 没有隔离级别:所有的命令在未提交之前都没有被实际执行

  • 非原子性:如果一条命令执行失败,其他命令正常执行,没有回滚

redis持久化

数据的备份与恢复

备份:通过SAVE指令用于创建当前数据库的备份 该指令会在redis的安装路径下创建dump.rdb文件

​ 创建redis备份文件也可通过指令BGSAVE,该命令在后台执行

恢复:只需要将dump.rdb移动到redis的安装目录下启动服务即可

​ 查看redis安装路径指令CONFIG GET dir

RDB:

(默认开启 文件名:dump.rdb)

  • 通过在临时区复制数据然后赋值到磁盘,可能会丢失数据。在复制数据时占用两倍内存容量,影响性能。

AOF:

(默认关闭 文件名:appendonly.aof )aof的开启:把配置文件中的appendonly no改为yes

  • 客户端的请求写命令会被append到AOF缓冲区内,

  • AOF缓冲区会根据AOF持久化策略[always everysec no]将操作sync同步到磁盘的AOF文件中

  • AOF文件大小超过重写策略或手动重写时会对AOF文件rewrite重写,压缩AOF文件容量

  • 如遇AOF文件损坏,通过/usr/local/bin/redis-check-aof–fix appendonlydir/appendonly.aof进行修复

    重写机制

    aof采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当aof文件大小超出所设定的阈值时,redis就会启动aof文件内容压缩,只保留可以恢复数据的最小指令集。可以使用命令bgrewriteaof

    重写的实现:

    aof重写和rdb过程一样,就是先fork出一个子进程将文件重写(先写临时文件然后rename)

    重写的触发:

    redis会记录上次rewrite的文件大小,默认是aof文件比上次大一倍且文件大于64MB触发

    auto-aof-rewrite-percentage设置重写的基准值,文件达到100%,即原来文件的两倍。

    auto-aof-rewrite-min-size设置文件的基准值,最小文件64MB,达到这个值开始重写

    缺点:

    • 相比rdb更占用内存空间
    • 恢复备份速度慢
    • 每次写与备份同步的话,有一定的性能压力
    • 存在bug造成恢复不能
  • 若两者同时开启系统默认AOF

主从复制(master/slaver)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jD0cQbeK-1662040787623)(image-20220803170758450.png)]

  • 读写分离

    master负责写 slave负责读

  • 一主多从设置

    创建一个文件夹myredis,把redist.conf复制到文件夹中,同时在文件夹中创建多个配置文件*.conf

    把redis.conf文件中的daemonize的no改为yes 即后台挂起

    配置文件内容为

include /myredis/redis6380.conf引入公共文件 绝对路径

pidfile /var/run/redis_6380.pid设置进程名称

port 6380设置监听端口号

dbfilename dump6380.rdb设置持久化文件名称

​ 以redis-cli -p 连接redis服务

​ info replication 指令可以查看当前服务的master/slave信息

​ 通过slaveof 设置当前服务为slave (设置成功后当前服务只能 读数据 不能写)

主从复制过程
  • 当slave连接到master成为slaver时,slaver主动向master发送同步数据请求
  • 当master收到slaver的同步请求后,master把数据持久化到磁盘rdb文件中,把rdb文件发送到slaver
  • slaver收到rdb文件进行数据的读取

注意

  • 全量复制 slaver接收到数据库文件后,将其存盘并加入到内存中
  • 增量复制 master每次进行写操作时都会主动同步到slaver
  • 每一次slaver重新连接master都会进行全量复制
薪火相传

任何一个slaver都可以成为另外一个slaver的master

例:m1(master)是s1(slaver)的master,s1(slaver)可以称为s2(slaver)的master

反客为主

手动版: 任何一个拥有slaver的slaver都可以在自己的master挂掉后通过slaveof no one使自己成为master

自动版:

​ 哨兵模式:

```go
//开启哨兵模式
redis-sentinel  myredis/sentinel.conf
//哨兵默认监视127.0.0.1 6379   相关设置在sentinel.conf中
//sentinel monitor mymaster 127.0.0.1 6380 1
//mymaster为为监控对象起的名字,后面的127.0.0.1为master的地址,6380为master的端口号,1为至少1个哨兵同意迁移的数量
```
选择条件
1、选择性优先级靠前的 优先级在redis.conf中默认:replica-priority 100 值越小优先级越高
2、选择偏移量最大的
3、选择runid最小的从服务 每个redis实例启动后都会随机生成一个40位的runid

**注意:**当master关闭后哨兵根据规则选举出新master后,原有的master重新启动后会默认称为master的slaver

redis集群搭建

//redis*.conf配置文件修改
//redis*.conf文件内容
include /myredis/redis.conf
pidfile /var/run/redis_*[端口号].pid
port [port]
dbfilename dump*[端口号].rdb
cluster-enabled yes //打开集群模式
cluster-config-file nodes-*[端口号].conf//设置节点配置文件
cluster-node-timeout 15000 //设置节点失联时间,超过该时间(毫秒),集群自动进行主从切换

创建六个集群实例后,进入安装redis地址的src路径下执行下列命令(注意注释redis.conf中的bind 127.0.0.1和protected mode设置为no)

redis-cli --cluster create --cluster-replicas 1 172.19.68.86:6380 172.19.68.86:6381 172.19.68.86:6382 172.19.68.86:6390 172.19.68.86:6391 172.19.68.86:6392
//此处不要用127.0.0.1,用真实ip  --cluster-replicas 1 以最简单的模式创建 即一个master配备一个slaver
//分配原则 各个主从服务器在不同的地址
//以集群方式连接
redis-cli -c -p 7001
//查看集群状态
cluster nodes

一个集群中一共有16384(0~16383)个slot(插槽)均匀的分布在集群的各个master中,如果master挂掉其slaver上位,如果该master重新启动则变为slaver

**注意:**如果一段插槽的主从都宕掉,redis服务是否继续依赖于cluster-require-full-coverage的值,如果是yes则整个集群都挂掉,如果为no则只是该段插槽不提供服务(数据不能读取,也不能往此段插槽写入数据)。

redis分区

分区是分割数据到多个Redis实例的处理过程,因此每个实例只保存key的一个子集。

范围分区

最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的Redis实例。

比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。

这种方式是可行的,并且在实际中使用,不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各 种对象的映射表,通常对Redis来说并非是好的方法。

哈希分区

另外一种分区方法是hash分区。这对任何key都适用,也无需是object_name:这种形式,像下面描述的一样简单:

  • 用一个hash函数将key转换为一个数字,比如使用crc32 hash函数。对key foobar执行crc32(foobar)会输出类似93024922的整数
  • 对这个整数取模,将其转化为0-3之间的数字,就可以将这个整数映射到4个Redis实例中的一个了。93024922 % 4 = 2,就是说key foobar应该被存到R2实例中。注意:取模操作是取除的余数,通常在多种编程语言中用%操作符实现。

发布订阅

开启三个客户端

第一个客户端发布 发布格式PUBLISH <频道名> 消息

另外两个客户端订阅频道 订阅格式SUBSCRIBE <频道名>

**重点:**发布与订阅的实现基于客户端连接的是同一个redis服务器

管道技术

Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:

  • 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
  • 服务端处理命令,并将结果返回给客户端。

redis管道技术(未完)

Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应

缓存穿透

缓存击穿

缓存雪崩

分布式锁

- 基于数据库实现分布式锁
- 基于缓存(redis)实现分布锁
- 基于zookeeper实现分布式锁

ACL(access contral list)访问控制列表

acl list
acl cat
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值