redis入门

redis是什么?

redis是一个c语言写的,可基于内存也可持久化的key-value数据库。

redis数据结构

1字符串(String)

2列表(list)

3集合(set)

4有序集合(sort set)

5哈希

关于key:

1key不要太长,尽量不要超过1024字节。这不仅消耗内存,而且会降低查找效率

2 key也不要太短。可读性会降低

3最好使用统一命名模式。

127.0.0.1:6379> set will "2"
OK
127.0.0.1:6379> get will
"2"
127.0.0.1:6379> incr will
(integer) 3
127.0.0.1:6379>

由于incr指令本身具有原子性。所以我们可以利用incr,incrby,decr,decrby等实现原子计数的效果。。如果某种场景下有3个客户端同时读取will的值(初始为2),然后对其同时进行加1.那么最好will的值一定是5。

list

redis在list的底层实现上并不是数组。而是一个链表。也就是说对于一个具有百万元素的list来说,在头尾插入一个新元素其时间是常数级别。但是,链表list元素定位会毕竟慢。

常用的操作有lpush,rpush,lrange。lrange可以从list中指定一个范围来提取元素

我们可以使用list来实现一个消息队列,而且可以确保先后顺序。利用lrange可以实现分页

set

set是一种无序集合

sadd添加,smembers列出所有元素 sismember 判断元素是否在集合中,存在返回1.不存在返回0.sunion合并集合。

sort set

zadd 添加。zrange 列出所有的元素

redis的两种持久化方式

RDB (redis database) AOF(Appand only file)

RDB在不同的时间点将redis存储数据生成快照并存储到磁盘

redis在进行数据持久化的过程中,会先将数据写入到一个临时的文件总。待持久化过程都结束,才会用这个临时文件替换上次持久化好的文件。

redis会单独fork一个进程来进行持久化,而主进程不会进行任何IO操作。这样就确保了redis的性能。

如果需要大规模数据恢复,且对数据的完整性不敏感,RDB比AOP高效。但是如果对数据完整性敏感RDB不适合。因为即使你每5分钟都持久化一次,当redis故障时仍然有5分钟的数据丢失

AOF将redis执行过的所有指令记录下来,在下次redis重启时将这些指令从前到后再重复执行一遍。

我们通过将redis.conf中的appendonly yes就可以打开aof。默认的持久化策略是fsync每秒一次。(fsync是把缓存中的写指令记录到磁盘中)因为在这种情况下redis仍然可以很好的处理性能,即使redis故障也只丢失1秒的数据。

如果在追加日志时,遇到磁盘空间满,inode满,断电等情况导致日志写入不完整,可以使用redis-check-aof工具来修复。

因为采用追加,如果不做任何处理,AOF文件会越来越大,因此redis为AOF假如重写(rewrite)。即当aof文件大小超过所设定的阙值,redis就会启动aof文件内容压缩,只保留可以恢复数据的最小指令集。假如我调用1000次incr的命令,那么aof中就有1000条指令,这是很低效的。完全可以把这1000条指令合并成一条set指令。这就是重写的原理。

再进行重写时仍然先写临时文件,全部完成再替换的流程,所以断电等都不好影响aof的可用性。

aof的另一个好处,当某同事不小心执行了flushall 导致redis内存中的数据全部被清空,只要redis配置了aof切文件还未被重写,就可以快速编辑aof文件。

aof的缺点,同样规模,文件体积大,切恢复速度慢。如果运气差会出现aof文件被写坏的情况。redis不会贸然执行这个文件,而且报错退出。可以使用redis-check-aof-fix来修复

aof 重写原理

在重写即将开始时,redis会创建一个重写子进程,这个子进程会首先读取现有的aof文件,并将其包含的指令进行分析压缩并写入到一个临时文件,同时主工作进程会将新接收到的指令一边累积到内存缓存区中,一边继续写入到原有的aof文件中,这样确保原有的aof文件的可用性,避免重写过程出现意外。当重写子进程完成重写工作后,会给父进程发一个信号,父进程收到信号后将内存中缓存的写指令追加到新的aof文件中,当追加结束,redis将新的aof文件代替旧的。

主从同步

redis支持主从同步,也支持一主多从。

1冗余备份,2提升读性能。比如消耗新能的sort就由从服务器来承担。

主从架构中,从服务器通常设置为只读模式,这样可以避免从服务器数据被误改

同步原理:

从服务器会向主服务器发送sync指令,当主服务器接到此命令后,会调用bgsave指令来创建一个字进程来进行数据持久化,也就是将主服务器的数据写入RDB中,在数据持久化期间,主服务器将执行的写指令都缓存到内存中。在bgsave执行完成后,主服务器会将持久化好的RDB文件发送到从服务器,从服务器得到此文件后会将其存储到磁盘上,然后再将其读取到内存中。这个动作完成后,住服务器会将这段时间缓存的写指令再以redis协议发送到从服务器。另外即使有多个从服务器同时发来sync指令,主服务器也只会执行1次bgsave。然后把持久化好的RDB文件发给多个下游。redis支持了增量同步策略。主服务器会在内存中维护一个缓冲区,缓冲区存储着将要发送给从服务器的内容。从服务器在主服务器出现网络断掉后,从服务器会尝试再次与主服务器连接,一旦成功,从服务器就会把希望同步的主服务器ID和希望请求的数据的便宜位置发送出去。主服务器接收到这样的同步请求后首先会验证主服务器的ID与自己是否匹配,其次检查请求的偏移位置是否存在于自己的缓冲区,如果都满足,主服务器就向从服务器发送增量。

redis事务

redis的4个指令

1multi用来组装一个事务

2exec执行一个事务

3discard取消一个事务

4watch监视一些key。一旦这些key在事务执行前被改变,则取消事务

127.0.0.1:6379> multi  #事务开始
OK
127.0.0.1:6379> incr uid #多条命令按顺序入队
QUEUED
127.0.0.1:6379> incr uid
QUEUED
127.0.0.1:6379> incr uid
QUEUED
127.0.0.1:6379> ping
QUEUED
127.0.0.1:6379> exec #执行
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG

我们可以看到queued这表示我在用multi组装事务时每一个命令都会进入到内存队列中缓存起来,如果出现queued表示这个命令成功插入缓存队列,在将来执行exec时,这些queued的命令都会被组装成一个事务来执行。

有关事务的错误基本是两类

1调用exec前的错误

调用exec之前的错误,可能是语法错误导致,也可能由于内存不足导致。只要出现某个命令无法成功写入缓存队列的情况,redis都会记录。在客服端执行exec时,redis都会拒绝执行这个事务。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> haha
(error) ERR unknown command 'haha'
127.0.0.1:6379> set name '1'
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

2调用exec之后的错误。

redis采用了不同的策略,完全不理睬这些错误而是继续向下执行事务中的其他命令。这是因为对于应用层面的错误并不是redis自身需要考虑和处理的问题。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 20
QUEUED
127.0.0.1:6379> sadd age 15
QUEUED
127.0.0.1:6379> set age 30
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) OK

watch可以帮我们实行乐观锁cas。它本身作用是监视key是否被改动过,而且支持同时监视多个key。只要还没真正触发事务,watch都会尽职尽责的监视,一旦发现某个key被修改,在执行exec时会返回nil表示事务无法触发

127.0.0.1:6379> set age 23
OK
127.0.0.1:6379> watch age
OK
127.0.0.1:6379> set age 24
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 25
QUEUED
127.0.0.1:6379> get age
QUEUED
127.0.0.1:6379> exec
(nil)



















































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值