redis学习(1)之redis基础和配置主从


内容来源为六星教育,这里仅作为学习笔记

redis介绍

redis是 一 个key-value存 储 系 统 。 它 支 持 存 储 的 value类型相对更多,包括string(字符串)、list(链 表)、set(集合)、zset(sorted set --有序集合)和 hash(哈希类型)。这些数据类型都支持push/pop、 add/remove及取交集并集和差集及更丰富的操作, 而且这些操作都是原子性的。在此基础上,redis支持 各种不同方式的排序。为了保证效率,数据都是缓存在 内存中

为什么会出现redis呢?

对于网页来说数据来自于数据库,而数据库实际上是存在这性能的瓶颈(一般单表早期的瓶颈就在2000w了–[索引的优化效率瓶颈])

即时是做了主从以及集群架构也依然还是会有速率的问题,因此这个时候以内存暂时存储数据的想法就横空出世了

redis特性

速度快

正常情况下,Redis执行命令的速度非常快,官方给出的数字是读写性能可以达到10万/秒,当然这也取决于机器的性能,但这里先不讨论机器性能上的差异,只分析一下是什么造就了Redis除此之快的速度,可以大致归纳为以下四点:

  1. Redis的所有数据都是存放在内存中的,,所以把数据放在内存中是Redis速度快的最主要原因。
  2. Redis是用C语言实现的,一般来说C语言实现的程序“距离”操作系统更近,执行速度相对会更快。
  3. Redis使用了单线程架构,预防了多线程可能产生的竞争问题。
  4. 作者对于Redis源代码可以说是精打细磨,曾经有人评价Redis是少有的集性能和优雅于一身的开源代码。

基于key-value

几乎所有的编程语言都提供了类似字典的功能,例如Java里的map、Python里的dict,类似于这种组织数据的方式叫作基于键值的方式,与很多键值对数据库不同的是,Redis 中的值不仅可以是字符串,而且还可以是具体的数据结构,这样不仅能便于在许多应用场景的开发,同时也能够提高开发效率。

Redis 的全称是REmote Dictionary Server,它主要提供了5种数据结构:字符串、哈希、列表、集合、有序集合,同时在字符串的基础之上演变出了位图( Bitmaps)和HyperLogLog两种神奇的“数据结构”,并且随着LBS ( Location BasedService,基于位置服务)的不断发展,Redis 3.2版本中加人有关GEO (地理信息定位)的功能,总之在这些数据结构的帮助下,开发者可以开发出各种“有意思”的应用。

丰富的功能

除了5种数据结构,Redis还提供了许多额外的功能:

  1. 提供了键过期功能,可以用来实现缓存。
  2. 供了发布订阅功能,可以用来实现消息系统。
  3. 支持Lua脚本功能,可以利用Lua创造出新的Redis命令。
  4. 提供了简单的事务功能,能在一定程度 上保证事务特性。
  5. 提供了流水线( Pipeline)功能,这样客户端能将一批命令-一次性传到Redis,减少网络的开销。

简单稳定

支持的语言多

持久化

主从复制

redis应用场景

缓存

缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速 座而且能够有效地降低后端数据源的压力。Redis 提供了键值过期时间设置,并且也提供 7灵活控制最大内存和内存溢出后的淘汰策略。可以这么说,一个合理的缓存设计能够为一 个网站的稳定保驾护航。第11章将对缓存的设计与使用进行详细说明。

排行榜系统

排行榜系统几乎存在于所有的网站,例如按照热度排名的排行榜,按照发布时间的排行榜,按照各种复杂维度计算出的排行榜,Redis 提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。

计数器

计数器在网站中的作用至关重要,例如视频网站有播放数、电商网站有浏览数,为了保证数据的实时性,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。

社交网站

赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常 比较大,而且传统的关系型数据不太适 合保存这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。

消息队列

消息队列系统可以说是一- 个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,但是对于般的消息队列功能基本可以满足。

redis基础数据类型及场景运用

网络io模型

https://user.qzone.qq.com/2598352200/blog/1578902149

字符串

字符串是redis最基础的数据结构。首先键都是字符串类型,而且其他几种数据结构都是在字符串类型基础上构建的,所以字符串类型能为其他四种类型结构的学习奠定基础
在这里插入图片描述

命令
-- 设置参数:
set key value
setnx key value
set key value xx
mset key value [key value ...]
-- 获取参数
get key
get key [key ...]
-- 计数
incr key
decr key
-- 是否存在
exists key
场景
缓存功能

如下图是比较典型的缓存使用场景,其中redis作为缓存层,mysql作为存储层大部分请求的数据都是从redis中获取。由于redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用
在这里插入图片描述
后台可以通过获取到用户的信息之后进行序列化操作,然后存入到redis中

<?php
UserInfo getUserInfo($id){
....
}
$userRedisKey - "user:info:".$id
$value = $redis->get($userRedisKey);
if ($value != null) {
$userInfo = unserialize($value)
}
?>
计数

许多应用都会使用redis作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。比如视频播放一次就自动加1

<?php
function incrVideoCounter($id)
{
$key = "video:playCount:".$id;
return $this->redis->incr($key);
}
?>
共享session

把session的session_id当key,把session信息作值存入redis里。

限速

很多应用处于安全的考虑,会在每次进行登入的时候,设置短信验证登入;而对于短信接口不被频繁访问,会限制用户每分钟获取验证码的频率,比如一份中不超过5次

<?php
$phomeNum = "138xxx";
$key = "shortMsg:limit:".$phomeNum;
// set key value ex 60 nx
$isExists = redis.set(key, 1, "EX 60", "NX");
if ($isExists != null || $redis->incr($key) <= 5) {
// 通过
} else {
// 限速
}
?>

当然也可以设置ip地址不能在1s之间内访问超过n次

哈希

哈希类型是指键值本身又是一个键值对结构(就是多维数组), value={{field, value},…{fieldN, valueN}}
字符串存储:
在这里插入图片描述
哈希存储:
在这里插入图片描述

命令
-- 设置
hset set field value
如:hset user:1 name shineyork
-- 获取
hget key field
如:hget user:1 name
-- 判断是否存在
hkeys key
场景

典型场景就是记录用户信息

列表

列表类型是用来存储多个有序的字符串,如图 a,b,c,d,e 从左到右组成一个有序的列表,列表中的每个字符串称为元素。在redis中,可以对列表两端插入(push)和弹出(pop),还可以指定范围的元素列表,获取指定索引下表的元素等。列表是种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。
在这里插入图片描述

命令
-- 从右边插入元素
rpush key value [value ...]
-- 实例
> rpush listkey c b a
> lrange listkey 0 -1
-- 从左边插入元素
lpush key value [value ...]
-- 获取列表指定索引下标元素
lindex key index
-- 获取列表长度
llen key
-- 删除
-- 从左侧弹出元素
lpop key
-- 从右侧弹出元素
rpop key
使用场景
消息队列

Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性
在这里插入图片描述

文章列表

每个用户有属于自己的文章列表,先需要分页展示文章列表。此时可以考虑使用列表因为列表不但是有序的,同时支持按照索引范围获取元素

集合

集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取原生。集合user:1:name包含着“peter”、“shineyork”、“cara”、“will”四个元素。
在这里插入图片描述

命令
-- 添加元素
sadd key element [element ...]
-- 实例
> exists myset
> sadd myset a b c
(integer)
> sadd myset a b
0
-- 删除元素
srem key element [element ...]
-- 从集合随机弹出元素
spop key
-- 获取所有元素
smembers key
使用场景

集合类型比较典型的使用场景是标签(tag)。例如一个用户可能对娱乐、体育比较感兴趣,另一个用户可能对历史、新闻比较感兴趣,这些兴趣点就是标签。有了这些数据就可以得到喜欢同一个标签的人,以及用户的共同喜欢的标签,这些数据对于用户体验以及增强用户黏合度比较重要

下面使用集合类型实现标签功能的若干功能
(1) 给用户添加标签

sadd user:1:tags tag1 tag2 tag5
sadd user:2:tags tag1 tag2 tag3
...
sadd user:k:tags tag1 tag2 tag3

(2) 给标签添加用户

sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2 user:3

开发提升:用户和标签的关系维护应该在一个事务内执行,放置部分命令失败造成的数据不一致,有关如何将两个命令放在一个事务

有序集合

有序集合相对哈希、列表、集合来说会有点点陌生, 但既然叫有序集合,那么它和集合必然有着联系,它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置-个分数(score)作为排序的依据。
在这里插入图片描述

数据结构是否允许重复元素是否有序应用场景
列表时间轴、消息队列等
集合标签
有序集合排行榜系统
命令
-- 添加成员
zadd key score member [score member ...]
-- 实例
> zadd user:name 300 php
(integer)1
> zadd user:name 1 .net 20 c++ 90 java 200 python
-- 计算排名
zrank key member
zrevrank key member
-- 删除成员
zrem key member [member ...]
使用场景

有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用户上传的视频做排行榜,榜单的维度可能是多个方面的:按照实际、按照播放数量、按照获得的赞数。比如以赞数这个维度,记录每天用户上传视频的排行榜
(1) 添加用户赞数
例如用户mike上传了一个视频,并获得了3个赞,可以使用有集合的zadd和zincrby功能:

zadd user:info:20200428 3 mike

如果之后再获得一个赞,可以使用zincrby
(2) 取消用户赞数
由于各种原因(例如用户注销、用户作弊需要将用户删除,此时需要讲用户从榜单删除掉,可以使用zrem。

zrem user:info:20200428 mike

(3) 展示获取赞数最多的是个用户

zrevrangebyrank user:info:20200428 0 9

(4) 展示用户信息以及用户分数
此功能将用户名作为键后缀,讲用户信息保存在哈希类型中,至于用户的分数和排名可以使用zscore和zrank两个功能

zscore user:info:20200428 mike
zrank user:info:20200428 mike

redis主从主从复制

背景

在实际的场景当中单一节点的redis容易面临风险
比如:
机器故障。我们部署到一台 Redis 服务器,当发生机器故障时,需要迁移到另外一台服务器并且要保证数据是同步的。而数据是最重要的,如果你不在乎, 基本上也就不会使用 Redis 了。
要实现分布式数据库的更大的存储容量和承受高并发访问量,我们会将原来集中式数据库的数据分别存储到其他多个网络节点上。
Redis 为了解决这个单一节点的问题,也会把数据复制多个副本部署到其他节点上进行复制,实现 Redis的高可用,实现对数据的冗余备份,从而保证数据和服务 的高可用。

什么是主从复制

在这里插入图片描述
在这里插入图片描述
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到 从节点。
默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

实践主从复制

首先确定目录
在这里插入图片描述

主从复制架构-规划

一主一从

容器名称容器IP地址映射端口号宿主机IP地址服务运行模式
redis5-masterxx.xx.xx.1506350 -> 6379xxxmaster
redis5-slavexx.xx.xx.1406340 -> 6379xxxslave

构建主从容器

对应的dockerfile

FROM alpine:3.11
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add gcc g++ libc-dev wget vim openssl-dev make linux-headers \
&& rm -rf /var/cache/apk/*
COPY ./redis-5.0.7.tar.gz redis-5.0.7.tar.gz
#通过选择更小的镜像,删除不必要文件清理不必要的安装缓存,从而瘦身镜像
#创建相关目录能够看到日志信息跟数据跟配置文件
RUN mkdir -p /usr/src/redis \
&& mkdir -p /redis/data \
&& mkdir -p /redis/conf \
&& mkdir -p /redis/log \
&& mkdir -p /var/log/redis \
&& tar -zxvf redis-5.0.7.tar.gz -C /usr/src/redis \
&& rm -rf redis-5.0.7.tar.gz \
&& cd /usr/src/redis/redis-5.0.7 && make \
&& cd /usr/src/redis/redis-5.0.7 && make install;
EXPOSE 6379
# CMD ["redis-server"]

构建容器

[root@localhost ~]# docker network create --subnet=192.160.1.0/24 redis5sm
355edc743429e308669dcd783a6fa4715504548531b63a36601148175e09ad8b
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e9da9cae0b4e bridge bridge local
eade643125b5 host host local
29835fbeb0ab none null local
355edc743429 redis5sm bridge local
[root@localhost masterandslave]# docker run -itd -v /redis_2004/masterandslave/master:/redis -p 6350:6379 --network=redis5sm --ip=192.160.1.150 --name redis5master redis5asm
af9b75289ac79235a97dfb3f5048f6f02d3b5f5fe4a0ff99920e0c0a5c9b634a
[root@localhost masterandslave]# docker run -itd -v /redis_2004/masterandslave/slave:/redis -p 6340:6379 --network=redis5sm --ip=192.160.1.140 --name redis5slave redis5asm

配置主从

这里通过命令构建

  1. 确保主服务器的redis-master的配置是ok的
    # bind 127.0.0.1
    protected-mode no
    
  2. 进入从服务器
    执行如下命令
    SLAVEOF 192.160.1.150 6379

配置即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值