Redis学习笔记

1.分布式与集群简单理解:
分布式:不同的多台服务器上面部署不同的服务模块,他们之间通过RPC/RMI之间通信和调用,对外提供服务和组内协作。
集 群:不同的多台服务器上面部署相同的服务模块,通过分布式调度软件进行统一的调度,对外提供服务和访问。
2.NoSQL定义:NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,泛指非关系型的数据库。NoSQL数据库的产生就是为了解决大规模数据集合,多重数据种类带来的挑战,尤其是大数据应用难题,包括超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
3.NoSQL特点:
(1)易扩展:NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。
(2)大数据量高性能:NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。一般MySQL使用Query Cache,表的更新都会导致Cache失效,是一种大粒度的Cache,在针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的Cache是记录级的,
是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了
(3)多样灵活的数据模型:NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。
4.大数据时代3V:Volume(海量),Variety(多样),Velocity(实时);互联网需求三高:高并发,高可扩,高性能
5.关系型数据库遵循ACID规则
(1) A (Atomicity):原子性:事务里的所有操作要么全部做完,要么都不做,只要有一个操作失败,整个事务就失败,需要回滚。
(2) C (Consistency) 一致性:数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
(3) I  (Isolation) 独立性:指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
(4)D (Durability) 持久性:指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
6.CAP理论:Consistency(强一致性),Availability(可用性),Partition tolerance(分区容错性。CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。分布式架构的时候必须做出取舍,在一致性和可用性之间取一个平衡
7.因为大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,为了解决这种关系数据库强一致性引起的可用性降低问题,BASE理论应运而生。BASE是下面三个术语的缩写:基本可用(Basically Available)软状态(Soft state) 最终一致(Eventually consistent);它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体的伸缩性和性能上的改观。
8.Redis是一个高性能的(key-value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,有五种数据类型:string,list,set,zset,hash.Redis通过单进程模型来处理客户端的请求以及对对读写等事件的响应,它是是通过对linux底层的epoll(Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃情况下的系统CPU利用率)函数的包装来做到的。
9.Redis可以用作内存存储和持久化(redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务),可以使用Redis模拟实现HttpSession的功能,使用Redis发布、订阅消息系统,使用Redis做定时器、计数器等。

10.Redis的key的相关用法:

set k1 v1 ex 3 设置string类型的键k1,值为“v1”,并设置过期时间为3s
keys * 返回所有的key
exists key k1 判断键k1是否存在,(存在1否则0)
del key 删除key
expire key 设置key的过期时间
ttl key 返回key距离过期剩余的时间
type key 返回可以的类型

11.string:redis最基本的类型,一个key对应一个value。string类型是二进制安全的。即redis的string可以包含任何数据。比如jpg图片或者序列化的对象 一个redis中字符串value最多可以是512M

set/get/del/append/strlen/
incr/desr/incrby/descby 使用这组命令时value必须是数字
getrange/setrange
mset/mget
getset 先get再set,返回key的旧值
setex set的时候同时设定过期时间
setnx 如果key不存在则设置key-value,存在则什么都不做

 12.list:字符串列表,按照插入顺序排序。可以添加元素到列表的头部或者尾部。它的底层实际是个链表,因此无论操作头和尾的元素效率都极高,但是对中间元素进行操作,效率就很惨淡了

lpush/rpush/lpop/rpop/llen/
lrem key  count value 删count个值为value的元素,返回实际删除的元素个数
ltrim key start end 截取指定范围的值后再赋值给key
rpoplpush source destination 移除source列表的最后一个元素,并将该元素添加到destination列表并返回 
lset key index value  
linsert key before/after pivot value1 value2 在值为pivot的元素之前/后插入value1 value2

 13.set:string类型的无序集合,不允许重复的成员。它是通过哈希表实现的。

 sadd/smembers/sismember  向集合添加元素/列出集合中的全部元素/判断集合中是否有某个元素
 scard 获取集合里面的元素个数
 srem key value1 value2  删除集合中的value1,value2元素
 srandmember key count 随机列出集合中的count个元素,如果超过最大数量就全部取出,如果写的值是负数,比如-3 ,表示需要取出3个,但是可能会有重复值
 spop key count 随机出栈count个元素
 smove source destination value1 value2  将source集合里面的元素value1,value2移动到destination集合中
 sdiff/sinter/sunion key2 key1 返回key2和key1集合取差集/交集/并集后的元素

14.zset:有序集合,和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。

zadd/zrange/ zrevrange [withscores] 
zrangebyscore    key minscore maxscore [withscore] [limit offset count ] 返回分数区间[minscore,maxscore]中的元素
zrevrangebyscore key minscore maxscore  逆序返回分数区间内的元素
zrem key value 删除元素 
zcard 返回集合中的元素个数 
zcount key minscore maxscore 返回分数区间[minsocre,maxscore]中的元素个数 
zscore key value 获得value的分数 
zrank key value 获得value的下标 
zrevrank key value 获得value的逆序下标

15.hash :一个string类型的field和value的映射表,hash特别适合用于存储对象。类似Java里面的Map<String,Object>

 hset/hget/hmset/hmget/hgetall/hdel/hlen
 hexists key field 在hash里面是否存在某个key
 hkeys/hvals  返回所有的key/value
 hincrby/hincrbyfloat key field value 对key中某个元素的value自增
 hsetnx  key field value 对key中某个元素field 赋值,如果该field存在则什么都不做直接返回

 16.redis有两种持久化方式:

 (1).RDB(Redis DataBase):在指定的时间间隔内将内存中的数据集快照(Snapshot)写入磁盘,恢复时将快照文件直接读到内存里。当需要保存 dump.rdb 文件时, Redis服务器会单独fork一个子进程(即复制一个与当前进程一样的进程,新进程的所有数据都和原进程一致,新进程作为原进程的子进程)来进行持久化,先将数据写入到一个临时文件中,等持久化过程结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性和一致性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。可以通过调用save和bgsave手动触发数据集保存操作。save的时候只管保存,其它不管,全部阻塞,而bgsave会在后台异步进行快照操作,快照同时还可以响应客户端请求。如果要停止rdb,save命令传一个空字符串即可。
(2).AOF(Append Only File):AOF采用文件追加方式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),redis重启的话就根据文件的内容将写指令从前到后执行一次以完成数据的恢复工作。由于AOF采用文件追加方式,文件会越来越大,为避免出现此种情况,出现了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集(例如命令对i进行了100次incrby,可直接set i为100).通常情况下AOF文件保存的数据集要比RDB文件保存的数据集完整,但是带来了持续的IO,而且AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的,因此性能要差一些
可以配置 Redis 多久将数据同步持久化到磁盘一次。有三个选项:
appendfsync always 每次有新命令追加到 AOF 文件时就立即记录到磁盘 ,性能较差但数据完整性比较好
appendfsync everysec 每秒一次,足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。默认策略
appendfsync no 从不同步,将数据交给操作系统来处理。更快,也更不安全。
如果AOF 文件出错可以使用自带的redis-check-aof程序修复。

 17.如果redis只做缓存使用,即只希望数据在服务器运行的时候存在,则可以不使用任何持久化方式.如果同时使用RDB和AOF,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集完整.RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。因此推荐结合使用RDB和AOF.

关于持久化时性能的考虑:因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。AOF重写的基础大小默认值64M太小了,可以适当调大到2G以上。默认超过原大小100%大小时重写可以改到适当的数值。如果不开启AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件来载入较新的那个。

18.Redis的事务:事务表示的是一组动作要么全部执行要么全部不执行。redis的事务的本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行执行而不会被其它命令插入。

悲观锁: 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁

乐观锁: 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制(提交版本必须大于记录当前版本)。乐观锁适用于多读的应用类型,这样可以提高吞吐量。

Redis的事务是下面4个命令来实现 :

  • multi     开始事务,置客户端为事务态。
  • exec     提交事务,执行从multi到此命令前的命令队列,置客户端为非事务态。 
  • discard 取消事务,置客户端为非事务态。
  • watch    监视指定的key.作用是如果事务提交exec时发现监视的键值对发生变化,事务将被取消

Redis使用WATCH命令基于CAS(check and set),是乐观锁的一种实现。在执行EXEC命令之前,如果Redis检测到至少有一个键被修改了,那么整个事务便会中止运行,然后EXEC命令会返回一个Null值,提醒用户事务执行失败,事务中的命令一个也不会执行。示例如下:

              客户端1

 

              客户端2

如上图,当客户端1对键a启用了watch,然后开启一个事务,但是事务尚未提交之前,客户端2修改了a值,然后客户端1执行exec提交事务,Redis监视到键a的值发生了变化,事务执行失败,返回一个nil.

 

Redis的事务不能保证原子性,即同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

 19.Redis的复制:主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主。主从复制可以用来实现读写分离以及容灾恢复。

复制原理:slave启动成功连接到master后会发送一个sync命令,Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步。

全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。

增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步

原文地址:https://www.cnblogs.com/pepper7/p/7095683.html