redis是个高性能缓存数据库,高性能的原因是直接对内存进行操作,redis是单线程的(所以不会造成频繁的切换线程消耗cpu资源),采用了多路复用技术(吞吐量非常高多个网络连接复用同个线程)
redis从2.6版本开始内嵌了lua,可以在redis中执行lua脚本,如此便可以将多个请求一次发送,减少网络开销,另外redis会将lua脚本一次执行完成(原子操作 不可分割)
redis内置lua操作
使用eval(执行脚本) script load(缓存脚本 并返回脚本内容的sha1校验和) evalsha(调用缓存脚本 使用返回的sha1校验和调用)
在redis的lua中 可以直接使用redis.call("命令",KEYS[1])来直接操作key
eval "local id = redis.call('INCR',KEYS[1]) return id" 1 a
KEYS[1]代表输入key占位符,1代表这段脚本有多少个keys 如果没有则填0 a代表redis中已经的key
另外可以使用AVGV来传递参数 同样索引也是从1开始的 如下
eval "local abc = ARGV[1] return abc" 0 123 ARGV代表输入参数占位符 123代表输入的参数
redis有三种集群模式,分别是
主从模式:可以实现读写分离,设置slave之后,当slave启动时会主动向master发送命令,master会将保存的快照和命令发送给slave,slave进行加载,这样就实现读写分离了
缺点:若master挂掉,则无法进行写操作
Sentinel(哨兵)
作用就是监控redis集群的运行状况,当master挂掉之后,sentinel会在slave中选取一个作为master,并会修改它们的配置文件,当挂掉的master重新启动时,就会变成一个slave 哨兵模式可以,当使用sentinel模式的时候,客户端就不要直接连接Redis,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。
Cluster
当数据量大到一台服务器装不下时,这个时候主从模式或sentinel模式就不能满足需求了,这个时候就要进行分片,将数据存储到多个Redis实例中,cluster模式就是做把redis的数据根据一定规则分配到多台机器,那么分片之后是如何查询的呢
客户端请求获得指定键的值时只需要向任意集群中的节点发送命令,该节点会判断这个键是否在本节点中,在的话直接获取返回,如果不在则返回给客户端一个重定向命令,并附带存储此键对应的节点的ip、端口、槽位。客户端重新发送请求即可。也可以配置令节点自动转发请求到指定节点处理再返回给客户端。当然这样在一定程度上会影响性能,可以由客户端配置缓存插槽和节点的信息来解决。
简而言之就是访问任意一台节点的时候都会给予你正确的响应,要么是数据要么是存在数据的节点地址
2.4 关于redis的持久化机制
RDB(redis默认开启)
每隔一定的时间把内存的数据作为一个快照保存到硬盘的文件上。默认900秒如果有1次修改就保存,300秒内有10次修改就保存,60秒内有10000次修改就保存
缺点: 保存时间太长,如果这段时间拓机那么将会丢失太多数据; 数据文件如果过大,恢复时会很慢
AOF(默认存在aof的文件就只先加载aof的存储文件)
aof与rdb不同的事,rdb是将内存中的数据拍一个快照保存到硬盘。而aof是将生成数据的命令保存到硬盘的文件中。
缺点:因为是将每一次的命令写入硬盘,所以通常它保存的文件要比rdb要大,恢复速度比rdb慢
如上所述,所以还是rdb与aof并存更好
2.5 redis的事务
命令名 | 作用 |
MULTI | 表示开始收集命令,后面所有命令都不是马上执行,而是加入到一个队列中。 |
EXEC | 执行MULTI后面命令队列中的所有命令。 |
DISCARD | 放弃执行队列中的命令。 |
WATCH | “观察“、”监控“一个KEY,在当前队列外的其他命令操作这个KEY时,放弃执行自己队列的命令 |
UNWATCH | 放弃监控一个KEY |
事务
redis的事务就是一组命令的集合,开始事务(multi)后 ,所有 的输入命令并不执行而是被缓存,可以通过watch监视一个或多个key 如果事务执行之前,该key被其它命令改动,则该事务会被打断
事务在执行(exec)时,如果某一命令(语法 编译)出错,则在exec时全部不执行,如果是运行时错误 类似给字符串进行自增操作 set abc abc incr abc 那么在exec时会执行其它未出错命令
并且一旦执行,之前watch过的便失效
2.6 redis的淘汰策略
将 Redis 用作缓存时, 如果内存空间用满, 就会自动驱逐老的数据
redis的淘汰策略一共有6种
noeviction:不删除策略,达到最大内存限制,如果需要更多内存则返回错误信息
allkeys-lru: 所有key通用,优先删除最近最少使用的key
volatile-lru:只限于设置了expire(过期时间)的部分,优先删除最近最少使用的key
allkeys-random:所有key通用,随机删除一部分key
volatile-random:只限于设置了expire的部分,随机删除一部分key
volatile-ttl:只限于设置了expire的部分,优先删除剩余时间较短的key
如果没有设置expire的key,不满足先决条件只限于设置了expire的部分,那么volatile行为和不删除策略一致
简而言之: 对于设置了expire的key,有删除最近最少使用的key,随机删除一部分key,删除剩余时间较短的key这三种策略。对于所有key,有不删除策略,删除较少使用的key,随机删除一部分key这几种策略