redis基础学习

一、redis介绍

redis是一个内存高速缓存数据库。它不是一个关系型数据库,redis是一个key-value存储系统,Redis是单线程的,基于事件驱动的。

二、redis特点

1.redis 以内存作为数据存储的截止,读写的效率很高。
2.存储在redis中的数据是持久化的,断电之后,数据不会丢失。redis的存储分为内存存储,磁盘存储和log文件,重启后,redis可以从磁盘重新将数据加载到内存中,这个可以通过配置文件进行配置,来实现redis的持久化。
3.redis支持主从模式,配置redis集群,便于支撑更大型的项目。
4.它具有丰富的数据类型,string,list,set,zset(sorted set),hash。
5.redis的所有操作都是原子性的,要么成功执行,要么失败完全不执行。单个操作是原子性的。多个操作也支持事物。
6.redis有着更为复杂的数据结构,并且提供对他们的原子性操作,不同于其他数据库,redis的数据类型基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
7.redis运行在内存中,但是可以持久化到磁盘,所以在对不同数据进行高速读写的时候需要权衡内存,数据量不能大于硬件内存。在内存中的一个优点是,相比在磁盘上复杂的数据结构,内存中操作起来就比较简单。

三、redis数据类型

redis支持5中数据类型:string(字符串),hash(哈希),list(列表),set(集合),zset(sorted set:有序集合)
1.string(字符串)
字符串是Redis最基本的数据结构,它将以一个键和一个值存储于Redis内部,它犹如Java的Map结构,让Redis通过键去找到值。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储512MB。
基本命令:
set key value --设置键值对
get key --通过键获取值
del key --通过 key,删除键值对
strlen key --求key指向字符串的长度
getset key value --修改原来 key 的对应值,并将旧值返回
append key value --将value追加到key值指向的字符串后面
getrange key start end --获取子串,获取start到end的子串。Redis 是以 0 开始计数的。

2.list(列表)
列表结构是 Redis 中一个常用的结构,它可以存储多个字符串,而且它是有序的,能够存储2的32次方减1个节点(超过40亿个节点)。
list列表是双向的,因此即可以从左到右,也可以从右到左遍历它存储的节点。
基本命令:
lpush key node1 [node2.]… --把节点 node1 加入到链表最左边
rpush key node1[node2]… --把节点 node1 加入到链表的最右边
lindex key index --读取下标为 index 的节点
llen key --求链表的长度
lpop key --删除左边第一个节点,并将其返回
rpop key --删除右边第一个节点,并将其返回
linsert key before|after pivot node --插入一个节点 node,并且可以指定在值为pivot 的节点的前面(before)或者后面(after))。如果没有值为对应 pivot 的,也会插入失败返回 -1
lpushx list node --如果存在list的链表,则插入节点 node, 并且作为从左到右的第一个节点
rpushx list node --如果存在list的链表,则插入节点 node, 并且作为从左到右的最后个节点
lrange list start end --获取链表 list 从 start 下标到 end 下标的节点值
lrem list count value --如果count为0,则删除所有值等于value的节点;
如果count不是0,则先对count取绝对值,假设记为abs,然后从左到右删除不大于abs个等于value的节点。
lset key index node --设置列表下标为 index 的节点的值为 node
ltrim key start stop --修剪链表,只保留从start到stop的区间的节点,其余的都删除掉。

3.set(集合)
Set是string类型的无序集合。Redis的集合不是一个线性结构,而是一个哈希表结构,它的内部会根据hash分子来存储和查找数据,
理论上一个集合可以存储2的32次方减1个节点(大约42亿)个元素,因为采用哈希表结构,所以对于 Redis 集合的插入、删除和查找的复杂度都是O(1),
我们需要注意3点:
对于集合而言,它的每一个元素都是不能重复的,当插入相同记录的时候都会失败。
集合是无序的。
集合的每一个元素都是 String 数据结构类型。
sadd key member1 [member2…] --给键为key的集合増加成员
scard key --统计键为key的集合成员数
sdiff key1 [key2] --找出两个集合的差集,参数如果是单key,那么Redis就返回这个key的所有元素
sdiftstore des key1 [key2] --先按sdiff命令的规则,找出key1和key2两个集合的差集,然后将其保存到des集合中。
sinter key1 [key2] --求key1和key2两个集合的交集,参数如果是单key,那么Redis就返冋这个key的所有元素
sinterstore des key1 key2 --先按sinter命令的规则,找出key1和key2两个集合的交集,然后保存到des中
sismember key member --判断member是否键为key的集合的成员
smembers key --返回集合所有成员
smove src des member --将成员member从集合src迁移到集合des中
spop key --随机弹出集合的一个元素
srandmember key [count] --随机返回集合中一个或者多个元素,count为限制返回总数,如果count为负数,则先求其绝对值
srem key member1[member2…] --移除集合中的元素,可以是多个元素
sunion key1 [key2] --求两个集合的并集,参数如果是单key,那么Redis就返回这个key的所有元素
sunionstore des key1 key2 --先执行sunion命令求出并集,然后保存到键为des的集合中

4.zset(有序集合)
Redis中zset和set一样也是string类型元素的集合,且不允许重复的成员,和无序集合的主要区别在于每一个元素除了值之外,它还会多一个分数。分数是一个浮点数,在Java 中是使用双精度表示的,根据分数,Redis就可以支持对分数从小到大或者从大到小的排序。
有序集合是依赖 key 标示它是属于哪个集合,依赖分数进行排序,所以值和分数是必须的,而实际上不仅可以对分数进行排序,在满足一定的条件下,也可以对值进行排序。
zadd key score1 value1 [score2 value2…] --向有序集合的 key,增加一个或者多个成员
zcard key --获取有序集合的成员数
zcount key min max --根据分数返回对应的成员列表,min 为最小值,max 为最大值,默认为包含 min 和 max 值,
采用数学区间表示的方法,如果需要不包含,则在分数前面加入“(”,注意不支持“[”表示
zincrby key increment member --给有序集合成员值为 member 的分数增加 increment
zinterstore desKey numkeys key1 [key2 key3…] --求多个有序集合的交集,并且将结果保存到 desKey 中
zlexcount key min max --求有序集合 key 成员值在 min 和 max 的范围
zrange key start stop [withscores] --按照分值的大小(从小到大)返回成员,加入 start 和 stop 参数可以截取某一段返回。如果输入可选项 withscores,则连同分数一起返回
zrank key member --按从小到大求有序集合的排行
zrangebylex key min max [limit offset count] --根据值的大小,从小到大排序,min 为最小值,max 为最大值;
limit 选项可选,当 Redis 求出范围集合后,会生产下标 0 到 n,然后根据偏移量 offset 和限定返回数 count,返回对应的成员
zrangebyscore key min max [withscores] [limit offset count] --根据分数大小,从小到大求取范围,选项 withscores 和 limit 请参考 zrange 命令和 zrangebylex 说明
zremrangebyscore key start stop --根据分数区间进行删除
zremrangebyrank key start stop --按照分数排行从小到大的排序删除,从 0 开始计算
zremrangebylex key min max --按照值的分布进行删除
zrevrange key start stop [withscores] --从大到小的按分数排序,参数请参见 zrange
zrevrangebyscore key max min [withscores] --从大到小的按分数排序,参数请参见 zrangebyscore
zrevrank key member --按从大到小的顺序,求元素的排行
zscore key member --返回成员的分数值
zunionstore desKey numKeys key1 [key2…] --求多个有序集合的并集,其中 numKeys 是有序集合的个数

5.hash(哈希)
哈希结构就如同Java的map一样,一个对象里面有许多键值对,它是特别适合存储对象的,如果内存足够大,那么一个Redis的hash结构可以存储2的32次方减1个键值对(0 多亿)。
在Redis中,hash是一个String类型的field和value的映射表。
基本命令:
hdel key field1[field2…] --删除hash结构中的某个(些)字段
hexists key field --判断 hash 结构中是否存在 field 字段
hgetall key --获取所有 hash 结构中的键值
hkeys key --返回hash中所有的键
hlen key --返回hash中键值对的数量
hset key filed value --在hash结构中设置键值对
hsetnx key field value --当hash结构中不存在对应的键,才设置值
hvals key --获取hash结构中所有的值

6.HyperLogLog(基数统计)
基数计数通常用来统计一个集合中不重复的元素个数,例如统计某个网站的UV,或者用户搜索网站的关键词数量。数据分析、网络监控及数据库优化等领域都会涉及到基数计数的需求。
HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。缺点就是有3%以内的误差。
PFADD key element [element …] --将所有元素参数添加到 HyperLogLog 数据结构中。
PFMERGE destkey sourcekey [sourcekey …] --命令将多个 HyperLogLog 合并为一个 HyperLogLog ,合并后的 HyperLogLog 的基数估算值是通过对所有 给定 HyperLogLog 进行并集计算得出的。
PFCOUNT key [key …] --返回给定 HyperLogLog 的基数估算值。

四、redis事务

Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。
在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
Redis事务没有隔离级别的概念:批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。
Redis不保证原子性:Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。
Redis事务的三个阶段:
开始事务
命令入队
执行事务
Redis事务相关命令:
   watch key1 key2 … : 监视一或多个key,如果在事务执行之前,被监视的key被其他命令改动,则事务被打断 ( 类似乐观锁 )
   multi : 标记一个事务块的开始( queued )
   exec : 执行所有事务块的命令 ( 一旦执行exec后,之前加的监控锁都会被取消掉 ) 
   discard : 取消事务,放弃事务块中的所有命令
   unwatch : 取消watch对所有key的监控

五、Redis的数据持久化

Redis支持两种方式的持久化,一种是RDB方式、另一种是AOF(append-only-file)方式。
前者会根据指定的规则“定时”将内存中的数据存储在硬盘上,而后者在每次执行命令后将命令本身记录下来。两种持久化方式可以单独使用其中一种,也可以将这两种方式结合使用。
RDB方式:
redis data base , 用于做内存数据的快照,此过程会fork一个子进程来操作,因此不用担心会影响当前的进程。
RDB触发条件有以下几种:
1.根据配置规则进行自动快照
2.用户执行SAVE(阻塞, 只管保存快照,其他的等待)或者BGSAVE(异步)命令
3.执行FLUSHALL命令
4.执行复制(replication)时

RDB 的优缺点
优点:
1.适合大规模的数据恢复。
2.如果业务对数据完整性和一致性要求不高,RDB是很好的选择,因为在两次同步期间的数据有可能会丢失。
缺点:
1.数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
2.备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍),最后再将临时文件替换之前的备份文件

AOF方式 :
Redis 默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

AOF的重写原理:
Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。
重写的流程:主进程会fork一个子进程出来进行AOF重写,这个重写过程并不是基于原有的aof文件来做的,而是有点类似于快照的方式,全量遍历内存中的数据,然后逐个序列到aof文件中。
在fork子进程这个过程中,服务端仍然可以对外提供服务,那这个时候重写的aof文件的数据和redis内存数据不一致了怎么办?
不用担心,这个过程中,主进程的数据更新操作,会缓存到aof_rewrite_buf中,也就是单独开辟一块缓存来存储重写期间收到的命令,
当子进程重写完以后再把缓存中的数据追加到新的aof文件。当所有的数据全部追加到新的aof文件中后,把新的aof文件重命名为,此后所有的操作都会被写入新的aof文件。
AOF 的优缺点
优点:数据的完整性和一致性更高
缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢

六、Redis集群

1.集群
先来简单了解下redis中提供的集群策略, 虽然redis有持久化功能能够保障redis服务器宕机也能恢复并且只有少量的数据损失,
但是由于所有数据在一台服务器上,如果这台服务器出现硬盘故障,那就是有备份也仍然不可避免数据丢失的问题。
在实际生产环境中,我们不可能只使用一台redis服务器作为我们的缓存服务器,必须要多台实现集群,避免出现单点故障。

2.主从复制
复制的作用是把redis的数据库复制多个副本部署在不同的服务器上,如果其中一台服务器出现故障,也能快速迁移到其他服务器上提供服务。 复制功能可以实现当一台redis服务器的数据更新后,自动将新的数据同步到其他服务器上主从复制就是我们常见的master/slave模式, 主数据库可以进行读写操作,当写操作导致数据发生变化时会自动将数据同步给从数据库。而一般情况下,从数据库是只读的,并接收主数据库同步过来的数据,一个主数据库可以有多个从数据库。

3.复制方式
全量复制
Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:
  1)从服务器连接主服务器,发送SYNC命令;
  2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
  3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
  4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
  5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
  6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

增量复制
Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。

4.哨兵机制
Redis的哨兵(sentinel) 系统用于管理多个 Redis 服务器,该系统执行以下三个任务:
监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
提醒(Notification):当被监控的某个Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master,
并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。
哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,
并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master.
每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,
则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown).
若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称odown),
通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置.
虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,
你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel)。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值