redis学习


前言

redis学习


一、Redis是什么?

Redis是NoSQL类型数据库下的一个子产品,基于内存操作,可持久化,规避IO,单进程,单线程写操作的KV非关系型数据库

二、Redis配置文件

引用地址

# Redis 配置文件

# 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写)
#
# 1k =>
1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb =>
1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024
bytes
#
# 内存配置大小写是一样的.比如 1gb 1Gb 1GB 1gB

# daemonize no 默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes
daemonize
yes

# 当redis在后台运行的时候,Redis默认会把pid文件放在/var/run/redis.pid,你可以配置到其他地址。
#
当运行多个redis服务时,需要指定不同的pid文件和端口
pidfile /var/run/redis.pid

# 指定redis运行的端口,默认是6379
port 6379

# 指定redis只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求,
# 在生产环境中最好设置该项
# bind
127.0.0.1

# Specify the path for the unix socket that will be used to listen for
#
incoming connections. There is no default, so Redis will not listen
# on a
unix socket when not specified.
#
# unixsocket /tmp/redis.sock
#
unixsocketperm 755

# 设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接
# 0是关闭此设置
timeout
0

# 指定日志记录级别
# Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
#
debug  记录很多信息,用于开发和测试
# varbose 有用的信息,不像debug会记录那么多
#
notice 普通的verbose,常用于生产环境
# warning 只有非常重要或者严重的信息会记录到日志
loglevel
debug

# 配置log文件地址
# 默认值为stdout,标准输出,若后台模式会输出到/dev/null
#logfile
stdout
logfile /var/log/redis/redis.log

# To enable logging to the system logger, just set 'syslog-enabled' to
yes,
# and optionally update the other syslog parameters to suit your
needs.
# syslog-enabled no

# Specify the syslog identity.
# syslog-ident redis

# Specify the syslog facility.  Must be USER or between LOCAL0-LOCAL7.
#
syslog-facility local0

# 可用数据库数
# 默认值为16,默认数据库为0,数据库范围在0-(database-1)之间
databases 16

################################ 快照
#################################
#
# 保存数据到磁盘,格式如下:
#
#   save
<seconds> <changes>
#
#
指出在多长时间内,有多少次更新操作,就将数据同步到数据文件rdb。
#   相当于条件触发抓取快照,这个可以多个条件配合
#
#
比如默认配置文件中的设置,就设置了三个条件
#
#   save 900 1  900秒内至少有1个key被改变
#   save 300
10  300秒内至少有300个key被改变
#   save 60 10000  60秒内至少有10000个key被改变

save 900 1
save 300 10
save 60 10000

# 存储至本地数据库时(持久化到rdb文件)是否压缩数据,默认为yes
rdbcompression yes

# 本地持久化数据库文件名,默认值为dump.rdb
dbfilename dump.rdb

# 工作目录
#
# 数据库镜像备份的文件放置的路径。
#
这里的路径跟文件名要分开配置是因为redis在进行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成时,
#
再把该该临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放在这个指定的路径当中。
#
#
AOF文件也会存放在这个目录下面
#
# 注意这里必须制定一个目录而不是文件
dir ./

################################# 复制
#################################

# 主从复制. 设置该数据库为其他数据库的从数据库.
#
设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
#
# slaveof
<masterip> <masterport>

# 当master服务设置了密码保护时(用requirepass制定的密码)
# slav服务连接master的密码
#
#
masterauth <master-password>


# 当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:
#
# 1)
如果slave-serve-stale-data设置为yes(默认设置),从库会继续相应客户端的请求
#
# 2)
如果slave-serve-stale-data是指为no,出去INFO和SLAVOF命令之外的任何请求都会返回一个
#    错误"SYNC with
master in progress"
#
slave-serve-stale-data yes

# 从库会按照一个时间间隔向主库发送PINGs.可以通过repl-ping-slave-period设置这个时间间隔,默认是10秒
#
#
repl-ping-slave-period 10

# repl-timeout 设置主库批量数据传输时间或者ping回复时间间隔,默认值是60秒
#
一定要确保repl-timeout大于repl-ping-slave-period
# repl-timeout 60

################################## 安全
###################################

# 设置客户端连接后进行任何其他指定前需要使用的密码。
#
警告:因为redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150K次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解
#
#
requirepass foobared

# 命令重命名.
#
# 在一个共享环境下可以重命名相对危险的命令。比如把CONFIG重名为一个不容易猜测的字符。
#
#
举例:
#
# rename-command CONFIG
b840fc02d524045429941cc15f59e41cb7be6c52
#
#
如果想删除一个命令,直接把它重命名为一个空字符""即可,如下:
#
# rename-command CONFIG ""

################################### 约束
####################################

# 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,
# 如果设置
maxclients 0,表示不作限制。
# 当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients
reached错误信息
#
# maxclients 128

# 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key
#
Redis同时也会移除空的list对象
#
#
当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作
#
#
注意:Redis新的vm机制,会把Key存放内存,Value会存放在swap区
#
#
maxmemory的设置比较适合于把redis当作于类似memcached的缓存来使用,而不适合当做一个真实的DB。
#
当把Redis当做一个真实的数据库使用的时候,内存使用将是一个很大的开销
# maxmemory <bytes>

# 当内存达到最大值的时候Redis会选择删除哪些数据?有五种方式可供选择
#
# volatile-lru ->
利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used )
# allkeys-lru ->
利用LRU算法移除任何key
# volatile-random -> 移除设置过过期时间的随机key
#
allkeys->random -> remove a random key, any key
# volatile-ttl ->
移除即将过期的key(minor TTL)
# noeviction -> 不移除任何可以,只是返回一个写错误
#
#
注意:对于上面的策略,如果没有合适的key可以移除,当写的时候Redis会返回一个错误
#
#       写命令包括: set setnx
setex append
#       incr decr rpush lpush rpushx lpushx linsert lset
rpoplpush sadd
#       sinter sinterstore sunion sunionstore sdiff sdiffstore
zadd zincrby
#       zunionstore zinterstore hset hsetnx hmset hincrby incrby
decrby
#       getset mset msetnx exec sort
#
# 默认是:
#
#
maxmemory-policy volatile-lru

# LRU 和 minimal TTL 算法都不是精准的算法,但是相对精确的算法(为了节省内存),随意你可以选择样本大小进行检测。
#
Redis默认的灰选择3个样本进行检测,你可以通过maxmemory-samples进行设置
#
# maxmemory-samples
3

############################## AOF ###############################


#
默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
#
所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
# 开启append
only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
#
但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。
#
你可以同时开启asynchronous dumps 和 AOF

appendonly no

# AOF文件名称 (默认: "appendonly.aof")
# appendfilename appendonly.aof

# Redis支持三种同步AOF文件的策略:
#
# no: 不进行同步,系统去操作 . Faster.
# always:
always表示每次有写操作都进行同步. Slow, Safest.
# everysec: 表示对写操作进行累积,每秒同步一次.
Compromise.
#
# 默认是"everysec",按照速度和安全折中这是最好的。
#
如果想让Redis能更高效的运行,你也可以设置为"no",让操作系统决定什么时候去执行
#
或者相反想让数据更安全你也可以设置为"always"
#
# 如果不确定就用 "everysec".

# appendfsync always
appendfsync everysec
# appendfsync no

# AOF策略设置为always或者everysec时,后台处理进程(后台保存或者AOF日志重写)会执行大量的I/O操作
#
在某些Linux配置中会阻止过长的fsync()请求。注意现在没有任何修复,即使fsync在另外一个线程进行处理
#
#
为了减缓这个问题,可以设置下面这个参数no-appendfsync-on-rewrite
#
# This means that while
another child is saving the durability of Redis is
# the same as "appendfsync
none", that in pratical terms means that it is
# possible to lost up to 30
seconds of log in the worst scenario (with the
# default Linux
settings).
#
# If you have latency problems turn this to "yes". Otherwise
leave it as
# "no" that is the safest pick from the point of view of
durability.
no-appendfsync-on-rewrite no

# Automatic rewrite of the append only file.
# AOF 自动重写
#
当AOF文件增长到一定大小的时候Redis能够调用 BGREWRITEAOF 对日志文件进行重写
#
#
它是这样工作的:Redis会记住上次进行些日志后文件的大小(如果从开机以来还没进行过重写,那日子大小在开机的时候确定)
#
#
基础大小会同现在的大小进行比较。如果现在的大小比基础大小大制定的百分比,重写功能将启动
#
同时需要指定一个最小大小用于AOF重写,这个用于阻止即使文件很小但是增长幅度很大也去重写AOF文件的情况
# 设置 percentage
为0就关闭这个特性

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

################################## SLOW LOG
###################################

# Redis Slow Log 记录超过特定执行时间的命令。执行时间不包括I/O计算比如连接客户端,返回结果等,只是命令执行时间
#
#
可以通过两个参数设置slow log:一个是告诉Redis执行超过多少时间被记录的参数slowlog-log-slower-than(微妙),
#
另一个是slow log 的长度。当一个新命令被记录的时候最早的命令将被从队列中移除

# 下面的时间以微妙微单位,因此1000000代表一分钟。
#
注意制定一个负数将关闭慢日志,而设置为0将强制每个命令都会记录
slowlog-log-slower-than 10000

# 对日志长度没有限制,只是要注意它会消耗内存
# 可以通过 SLOWLOG RESET
回收被慢日志消耗的内存
slowlog-max-len 1024

################################ VM ###############################

### WARNING! Virtual Memory is deprecated in Redis 2.4
### The use of
Virtual Memory is strongly discouraged.

# Virtual Memory allows Redis to work with datasets bigger than the
actual
# amount of RAM needed to hold the whole dataset in memory.
# In
order to do so very used keys are taken in memory while the other keys
# are
swapped into a swap file, similarly to what operating systems do
# with
memory pages.
#
# To enable VM just set 'vm-enabled' to yes, and set the
following three
# VM parameters accordingly to your needs.

vm-enabled no
# vm-enabled yes

# This is the path of the Redis swap file. As you can guess, swap
files
# can't be shared by different Redis instances, so make sure to use a
swap
# file for every redis process you are running. Redis will complain if
the
# swap file is already in use.
#
# The best kind of storage for the
Redis swap file (that's accessed at random)
# is a Solid State Disk
(SSD).
#
# *** WARNING *** if you are using a shared hosting the default
of putting
# the swap file under /tmp is not secure. Create a dir with access
granted
# only to Redis user and configure Redis to create the swap file
there.
vm-swap-file /tmp/redis.swap

# vm-max-memory configures the VM to use at max the specified amount
of
# RAM. Everything that deos not fit will be swapped on disk *if* possible,
that
# is, if there is still enough contiguous space in the swap
file.
#
# With vm-max-memory 0 the system will swap everything it can. Not
a good
# default, just specify the max amount of RAM you can in bytes, but
it's
# better to leave some margin. For instance specify an amount of
RAM
# that's more or less between 60 and 80% of your free
RAM.
vm-max-memory 0

# Redis swap files is split into pages. An object can be saved using
multiple
# contiguous pages, but pages can't be shared between different
objects.
# So if your page is too big, small objects swapped out on disk will
waste
# a lot of space. If you page is too small, there is less space in the
swap
# file (assuming you configured the same number of total swap file
pages).
#
# If you use a lot of small objects, use a page size of 64 or 32
bytes.
# If you use a lot of big objects, use a bigger page size.
# If
unsure, use the default :)
vm-page-size 32

# Number of total memory pages in the swap file.
# Given that the page
table (a bitmap of free/used pages) is taken in memory,
# every 8 pages on
disk will consume 1 byte of RAM.
#
# The total swap size is vm-page-size *
vm-pages
#
# With the default of 32-bytes memory pages and 134217728 pages
Redis will
# use a 4 GB swap file, that will use 16 MB of RAM for the page
table.
#
# It's better to use the smallest acceptable value for your
application,
# but the default is large in order to work in most
conditions.
vm-pages 134217728

# Max number of VM I/O threads running at the same time.
# This threads
are used to read/write data from/to swap file, since they
# also encode and
decode objects from disk to memory or the reverse, a bigger
# number of
threads can help with big objects even if they can't help with
# I/O itself
as the physical device may not be able to couple with many
# reads/writes
operations at the same time.
#
# The special value of 0 turn off threaded
I/O and enables the blocking
# Virtual Memory
implementation.
vm-max-threads 4

############################### ADVANCED CONFIG
###############################

# 当hash中包含超过指定元素个数并且最大的元素没有超过临界时,
#
hash将以一种特殊的编码方式(大大减少内存使用)来存储,这里可以设置这两个临界值
# Redis
Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,
#
这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value
redisObject的encoding为zipmap,
#
当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。
hash-max-zipmap-entries
512
hash-max-zipmap-value 64

# list数据类型多少节点以下会采用去指针的紧凑存储格式。
#
list数据类型节点值大小小于多少字节会采用紧凑存储格式。
list-max-ziplist-entries
512
list-max-ziplist-value 64

# set数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储。
set-max-intset-entries
512

# zsort数据类型多少节点以下会采用去指针的紧凑存储格式。
#
zsort数据类型节点值大小小于多少字节会采用紧凑存储格式。
zset-max-ziplist-entries
128
zset-max-ziplist-value 64

# Redis将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用
#
#
当你的使用场景中,有非常严格的实时性需要,不能够接受Redis时不时的对请求有2毫秒的延迟的话,把这项配置为no。
#
#
如果没有这么严格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存
activerehashing yes

################################## INCLUDES
###################################

# 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
#
include /path/to/local.conf
# include /path/to/other.conf

三、Redis三种底层数据结构

命令
OBJECT ENCODING    key
  • String有str、embstr、int
  • List有integer、quicklist

简单动态字符串

  • SDS Redis是C语言写的,但是对于Redis的字符串,却不是C语言中的字符串以’\0’结尾的字符数据组,而是自主创建了simple dynamic string SDS的抽象类型
strut sdshdr{
	//字符长度
	int len;
	//记录buf数组中未使用字节的数量
	int free;
	// 字节数组,用于保存字符串
	char buf[]'
}

SDS特性:

  1. 读取len属性的时间复杂度为O(1)
  2. 杜绝缓冲区溢出,先判断剩余内存空间是否足以容纳数据,不满足则会先进行扩容
  3. 减少修改字符串的内存重新分配次数,扩容多分,释放时先不回收空间
  4. 二进制安全,以len属性来判断字符串是否结束

链表

typedef struct list{
     //表头节点
     listNode *head;
     //表尾节点
     listNode *tail;
     //链表所包含的节点数量
     unsignedlong len;
     //节点值复制函数
     void (*free) (void *ptr);
     //节点值释放函数
     void (*free) (void *ptr);
     //节点值对比函数
     int (*match) (void *ptr,void *key);
}list;

链表特性:

  1. 双端:具有前置节点和后置节点的引用,获取两个节点时间复杂度为O(1)
  2. 无环
  3. 带链表长度计数器,通过len属性获取链表的时间复杂度为O(1)
  4. 多态,使用void*指针来保存节点值,可以保存不同类型的值

压缩表

相当于元素少或者元素不大的时候会先把元素紧密排序在一起

跳跃表

通过空间换时间的方式提高查询效率
性质:

  1. 由很多层结构组成
  2. 每一层都是一个有序的链表,排列顺序为由高层到底层,都至少包含两个链表节点
  3. 底层包含了所有元素
  4. 如果某一元素出现在某一层的链表中,那么该层链表之下也会出现该元素
  5. 链表中每个节点包含了两个指针,一个指向上一层,一个指向下一层同一链表节点
    操作:
  6. 搜索,先从高层的链表节点开始,如果比当前节点大且比当前节点的下一个节点小则往下一层找,以此类推,如果找到则返回,否则返回空
  7. 插入:先确认插入的层数,类似于抛硬币,如果正面则累加,如反面则停止,将最后记录正面的次数作为插入的层数,当确认插入的层数k后,则需要将新元素插入从底层到k层
  8. 删除:在各层找到指定值的节点进行删除,如果删除后只剩头尾节点则可以删除这一层

四、redis和memcached的区别

  1. memcached只支持简单的String类型,redis支持多种数据类型
  2. memcached纯内存操作,redis支持持久化

五、秒杀场景,如何确保商品不会超卖

  1. 事务并发控制,对数据加行锁
  2. 使用redis的decr,单线程模式

六、redis五大数据类型应用场景

String

  1. 保存session
  2. 字符串
  3. 对象
  4. 文件
  5. 统计
  6. 限流

List

  1. lpush k1 a b c d e f
  2. lrange k1 0 -1
  3. rpush k2 a b c d e f
  4. rrangge k2 0 -1
  5. 可实现栈,队列,LINDEX可以实现数组
  6. LTRIM k1 0 2 裁剪数据

Hash

  1. hset
  2. hget
  3. hmset
  4. hmget
  5. hvals
  6. hkeys
  7. hincrby
    详情页
    聚合

Set

  1. sadd k1 xxoo ooxx xoxo oxox
  2. smembers k1 – 返回所有,无序
  3. srangmember k1 3 – 正数(不够数只返回拥有的数)负数(不够数返回重复的数)
  4. spop – 弹出一个
  5. sunion k1 k2 --并集
  6. sinter k1 k2 --交集
  7. sdiff k1 k2 --差集
    去重
    无序
    随机事件
    抽奖
    验证码
    微信红包

ZSet

  1. zadd k1 2.2 k4 3.1 k2 1.6 k3

  2. zrange k1 0 -1 withscores – 默认按score排序

  3. zrange k1 0 1 – 取出前面较小的两个

  4. zrevrange k1 0 1 --取出较大的那两个,倒序,热榜

    去重
    有序
    排行榜
    翻页
    动态

七、持久化

save指令---->将快照信息写进save里面

防止数据的意外丢失,保证数据的安全性

RDB快照存储

定时备份(快照)体积和数据相近 I/O快

数据量过大,单线程效率较低

后台执行:bgsave

默认触发时机:
save 900 1
save 300 10
svae 1 10000
在这里插入图片描述
弊端:

  1. 存储量较大,效率较低
  2. 大数据IO性能较低
  3. 基于fork创建线程,内存产生额外消耗
  4. 宕机有数据丢失危险

AOF日志存储

手动开启AOF重启,只会读取AOF
存储写命令,体积大,可以通过调控参数来调节触发时机

  1. 实时:每操作一次就发生一次I/O 效率较低,但数据至多只会丢一条
  2. 每秒:宕机只会丢失1秒以内的数据
  3. no (系统控制)由系统控制周期同步

在这里插入图片描述

AOF重写:降低磁盘空间,提高恢复数据速度,优化指令

在这里插入图片描述
在这里插入图片描述
使用场景:
在这里插入图片描述

watch key
unwatch key
multi
exec
discard

九、分布式锁的实现

set num 10
setnx lock-num 1
inclrby num -1
del lock-num

宕机,不能释放已占有锁

设置过期时间
expire lock-num 20

带来问题:没有在规定时间内完成业务,锁超时(需要估计业务时间),可能会释放别人的锁
给一个特定标识,当释放锁的时候判断当前的这个是否是当前事务的锁,如果不是则放弃释放

使用redission框架来解决问题

十、过期删除策略expire---->到期数据

使用设置key的过期时间,可以减少内存的消耗

定期删除

随机抽查每秒花费固定的cpu资源维护内存

定时删除

到点删除,可能会带来问题是正在使用的数据也会删除掉,导致请求直接到数据库

惰性删除

数据到达过期时间,不做处理,等下次访问该数据的时候做判断,过期则删除,返回不存在
节约cpu资源,但占用内存

十一、逐出算法—>内存不足

指的是添加新数据的时候,先去去检测内存是否充足,如果不满足存储该数据的最小内存要求,redis则会删除一些数据为当前指令清理存储空间,清理旧数据的算法被称为逐出算法,这个算法不一定会执行成功,尝试多次以后还是没有达到存储新数据的要求时,则会报出OOM异常
在这里插入图片描述

十二、主从复制

在这里插入图片描述

十三、哨兵模式---->主要解决问题master节点宕机

在这里插入图片描述
哨兵模式是一个分布式系统,用于对主从结构的每台服务器进行监控,当主节点出现故障的时候通过投票机制来选择新的master并将所有的slave连接到新的master。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十四、常见问题

缓存预热

缓存雪崩

在这里插入图片描述
在这里插入图片描述

缓存击穿

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

缓存穿透

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

十六、单机问题

CAP问题
C:一致性
A:可用性
P:分区容错性

  1. 单点故障不可用
    (全量,主从复制,多台)主备集群--------->保证高可用
    解决:
    强一致性:备机全同步
    弱一致性:可能会丢数据
    最终一致性:有一个黑盒保证与主机之间的强一致性

  2. 压力/性能问题:数据量大
    (扩容?分片,不是全量)分片集群

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值