Redis笔记

113 阅读12分钟

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

NoSQL概念

NoSQL,指非关系型数据库,不支持SQL语法。关系型数据库,每次操作关系型数据库时都是I/O操作,I/O操作是主要影响程序执行性能原因之一,连接数据库关闭数据库都是消耗性能的过程。尽量减少对数据库的操作,能够明显的提升程序运行效率。

常见NoSQL数据库

Memcached :键值对,内存型数据库,所有数据都在内存中。

Redis:和Memcached类似,还具备持久化能力。

HBase:以列作为存储。

MongoDB:以Document做存储。

NoSQL分类

键值(Key-Value)存储数据库

键值存储数据库。用key-value的方式来存储数据,其中key和value可以是简单的数据,也可以是复杂的对象。key作为唯一的标识符,优点是查询速度比sql快多了,但是缺点也很明显,它无法像关系型数据库一样自由使用条件过滤(比如:where条件语句),如果你不知道去哪里找数据,就会从头遍历所有的数据,这就会消耗大量计算。

Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB

列存储数据库

相对于行式存储的数据库(Oracle、MySQL、SQL Server 等数据库都是采用的行式存储),列式数据库是将数据按照列存储到数据库中,这个做可以大量降低系统的I/O,适合于分布式文件系统,不足在于功能相对有限。

列式数据库将数据按照列进行存储,因为每列的数据格式是相同的,在存储过程时,可以使用有效的压缩算法进行压缩存储,压缩后的数据容量变小,所以降低了I/O

Cassandra, HBase, Riak

文档型数据库

文档型数据库用来管理文档,在数据库中文档作为处理信息的基本单位,一个文档就相当于一条记录

CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源

图形(Graph)数据库

利用了图这种数据结构存储了实体(对象)之间的关系。最典型的例子就是社交网络中人与人的关系,数据模型主要是以节点和边(关系)来实现,特点在于能高效地解决复杂的关系问题。

如:Neo4J, InfoGrid, Infinite Graph。

Redis简介

Redis是使用C语言进行编写的

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

Redis以slot(槽)作为数据存储单元,每个槽中可以存储N多个键值对。Redis中固定具有16384。理论上可以实现一个槽是一个Redis。每个向Redis存储数据的key都会进行crc16算法得出一个值后对16384取余就是这个key存放的slot位置

Redis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

Redis 优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

Redis数据类型(面试)

Redis中数据是key-value形式。不同类型Value是有不同的命令进行操作。key为字符串类型,value常用类型:

  • String 字符串

  • Hash 哈希表

  • List 列表

  • Set 集合

  • Sorted Set 有序集合(zSet)

Redis命令相关手册有很多,下面为其中比较好用的两个

www.redis.net.cn/order/

doc.redisfans.com/

Redis持久化策略(面试问题)

Redis不仅仅是一个内存型数据库,还具备持久化能力。

一共包含两种持久化策略:RDB 和 AOF

RDB(Redis DataBase)

默认情况下,Redis使用RDB模式,该模式在指定的时间间隔内生成数据快照(snapshot),默认保存到dump.rdb文件中。当redis重启后会自动加载dump.rdb文件中内容到内存中。

可以使用SAVE(同步)或BGSAVE(异步)手动保存数据

save 内存生存快照,将快照保存到磁盘中,对外停止提供服务

bgsave 在保存快照到磁盘中时,也可以对外提供服务,在保存快照时,会在内存中额外生成快照区用于保存数据,保存快照区,数据区,是分离的。内存中快照区在写入磁盘的过程,不影响内存的数据变更。

可以设置服务器配置的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令,可以通过save选项设置多个保存条件,但只要其中任意一个条件被满足,服务器就会执行BGSAVE命令。  例如:

save 900 1
save 300 10
save 60 10000

那么只要满足以下三个条件中的任意一个,BGSAVE命令就会被执行。计时单位是必须要执行的时间,

save 900 1 ,每900秒检测一次。在并发量越高的项目中Redis的时间参数设置的值要越小。   服务器在900秒之内,对数据库进行了至少1次修改 ,生成快照   服务器在300秒之内,对数据库进行了至少10次修改 ,生成快照   服务器在60秒之内,对数据库进行了至少10000次修改,生成快照

优点

​ rdb文件是一个紧凑文件,直接使用rdb文件就可以还原数据。

​ 数据保存会由一个子进程进行保存,不影响父进程做其他事情。

恢复数据的效率要高于aof

缺点

每次保存点之间导致redis不可意料的关闭,可能会丢失数据

​ 由于每次保存数据都需要fork()子进程,在数据量比较大时可能会比较耗费性能

AOF(AppendOnly File)

用文件记录命令流程,每1秒中追加这一秒执行的命令

AOF默认是关闭的 appendor no ,要在配置文件redis.conf中开启AOF。Redis支持AOF和RDB同时生效,如果同时存在,AOF优先级高于RDB(Redis重新启动时会使用AOF进行数据恢复)

AOF原理:监听执行的命令,如果发现执行了修改数据的操作,同时直接同步到数据库文件中,同时会把命令记录到日志中。即使突然出现问题,由于日志文件中已经记录命令,下一次启动时也可以按照日志进行恢复数据,由于内存数据和硬盘数据实时同步,即使出现意外情况也需要担心。

优点

​ 相对RDB数据更加安全。

缺点

​ 相同数据集AOF要大于RDB

​ 相对RDB可能会慢一些

Redis主从复制

Redis支持集群功能。为了保证单一节点可用性,redis支持主从复制功能。每个节点有N个复制品(replica),其中一个复制品是主(master),另外N-1个复制品是从(Slave),也就是说Redis支持一主多从。

一个主可有多个从,而一个从又可以看成主,它还可以有多个从。

一个主提供服务,多个从进行备份,防止数据丢失。

主从优点

增加单一节点的健壮性,从而提升整个集群的稳定性。(Redis中当超过1/2节点不可用时,整个集群不可用)

从节点可以对主节点数据备份,提升容灾能力。

读写分离。在redis主从中,主节点一般用作写(具备读的能力),从节点只能读,利用这个特性实现读写分离,写用主,读用从

哨兵(Sentinel)

在redis主从模型是只有主(Master)具备写的能力,而从(Slave)只能读。如果主宕机,整个节点不具备写能力。但是如果这时让一个从变成主,整个节点就可以继续工作。即使之前的主恢复过来也当做这个节点的从即可。

Redis的哨兵就是帮助监控整个节点的,当主节点宕机等情况下,帮助重新选取主。

Redis中哨兵支持单哨兵和多哨兵。单哨兵是只要这个哨兵发现master宕机了,就直接选取另一个master。而多哨兵是根据我们设定,达到一定数量哨兵认为master宕机后才会进行重新选取主

一主多从搭建

  1. 关闭redis

  2. 新建目录

    mkdir /usr/local/replica
    
  3. 将redis 复制到新建的目录

    cp -r /usr/local/redis/bin /usr/local/replica/master
    
  4. 修改从的配置文件

master配置

vim /usr/local/replica/master/redis.conf 
prot 6001

slave1配置

vim /usr/local/replica/slave1/redis.conf 
prot 6001
replicaof 192.167.1.179 6001

slave2配置

vim /usr/local/replica/slave2/redis.conf 
prot 6003
replicaof 192.167.1.179 6001
  1. 启动Redis

Redis 命令

通用操作

keys : 显示redis中的key

根据表达式,显示redis中的key。

返回值: redis中的key列表

语法: keys 表达式 [如: keys * ]

exists : 判断key是否存在

判断key是否存在。

语法:exists key名称

返回值:存在返回数字,不存在返回0

ttl : 查看key的剩余过期时间

查看key的剩余过期时间

语法:ttl key

返回值:返回剩余时间,如果不过期返回-1

expire : 设置key的过期时间

设置key的过期时间,单位秒

语法:expire key 秒数

返回值:成功返回1,失败返回0

persist : 删除key的有效时长

删除key的有效时长

语法: persist key

返回值:返回删除有效时长的key的个数。

del : 根据key删除

根据key删除键值对。

返回值:被删除key的数量

语法:del key

flushall:清空redis中所有键值对

清空redis中所有键值对

语法: flushall

dbsize:键值对数量数

返回redis中数据库键值对数量数

语法: dbsize

select:切换数据库

切换使用的数据库,Redis默认安装时有16个数据库,编号索引是0~15。默认链接redis使用的是0号数据库,可以自主切换数据库。

语法: select 数据库索引

字符串值(String)

set : 设置指定key的值

如果key不存在是新增效果,如果key存在是修改效果。键值对是永久存在的。

语法:set key value

返回值:成功OK

get : 获取指定key的值

语法:get key

返回值:key的值。不存在返回nil

setnx : 当且仅当key不存在时才新增

key不存在时,增加,key存在时无法修改。

语法:setnx key value

返回值:不存在时返回1,存在返回0

setex : 设置key的存活时间,并修改值

无论是否存在指定key都能新增,如果存在key覆盖旧值。同时必须指定过期时间。

语法:setex key seconds value

返回值:OK

mset:批量添加数据

mget:批量查询数据

哈希表(Hash)

Hash类型的值中包含多组field value

hset:添加

给key中field设置值。

语法:hset key field value

返回值:成功1,失败0

hget:查询

获取key中某个field的值

语法:hget key field

返回值:返回field的内容

hmset:给key中多个filed设置值

给key中多个filed设置值

语法:hmset key field value field value ...

返回值:成功OK

hmget: 获取key中多个field的值

一次获取key中多个field的值

语法:hmget key field field

返回值:value列表

hkeys:查询key中所有的field

获取key中所有的field名称

语法:hkeys key

返回值: field名称列表

hvals:查询key中所有field的值

获取key中所有field的值

语法:hvals key

返回值:value列表

hgetall:获取Key所有field和value

获取所有field和value

语法:hgetall key

返回值:field和value交替显示列表

hdel:删除key中多个field

删除key中任意个field

语法:hdel key field field ...

返回值:成功删除field的数量,当key对应的所有field全部删除,自动删除key。

列表(List)

rpush:末尾插值

向列表末尾中插入一个或多个值

语法;rpush key value value

返回值:列表长度

lrange:查询

返回列表中指定区间内的值。可以使用-1代表列表末尾

list中下标有两种计数方式,头->尾 0,1,2,3 .... 尾->头 -1,-2,-3 ...

语法:lrange list 0 -1

返回值:查询到的值

lpush:插值

将一个或多个值插入到列表前面

语法:lpush key value value

返回值:列表长度

llen:获取列表长度

获取列表长度

语法:llen key

返回值:列表长度

lrem:删除列表中元素

删除列表中元素。count为正数表示从左往右删除的数量。负数从右往左删除的数量。

语法:lrem key count value

返回值:删除数量。

集合(Set)

set和java中集合一样。

sadd:添加

向集合中添加内容。不允许重复。

语法:sadd key value value value

返回值:成功新增元素个数

scard:查询

返回集合元素数量

语法:scard key

返回值:集合长度

smembers:查看set内容

查看集合中元素内容

语法:smembers key

返回值:集合中元素

有序集合(Sorted Set)

有序集合中每个value都有一个分数(score),根据分数进行排序。

zadd:添加有序set

向有序集合中添加数据

语法:zadd key score value score value

返回值:长度

zrange:查看有序set

返回区间内容,withscores表示带有分数

语法:zrange key 区间 [withscores]

返回值:值列表

zcard:查看有序set元素数量

返回集合中元素数量

语法: zcard key

zrem:删除有序set元素

删除集合中元素

语法: zrem key value1 value2 [...]