近 期参加了江老师关于Redis的培训,加深了对Redis数据库的理解。
●目录●
一 redis适用场景
二 redis优势
三 Redis数据类型
四 redis持久化
五 redis架构
●内容●
一 redis适用场景
Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,似乎Redis更像一个加强版的Memcached。
1 会话缓存(Session Cache)
最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached) 的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的。
2 队列
Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。
3 全页缓存
大型互联网公司都会使用Redis作为缓存存储数据,提升页面相应速度。即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降。
4 排行榜/计数器
Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单。
二 Redis优势
1 性能极高
Redis能读的速度是110000次/s,写的速度是81000次/s 。
2 丰富的数据类型
Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
3 原子
Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
4 丰富的特性
Redis还支持 publish/subscribe, 通知, key 过期等等特性
MySQL+Memcached 演变 MySQL+Redis
MySQL适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,遇到了很多问题:
• MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。
• Memcached与MySQL数据库数据一致性问题。
• Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。
• 跨机房cache同步问题
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:
• Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
• Redis支持数据的备份,即master-slave模式的数据备份。
• Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
三 Redis数据类型
Redis支持五种数据类型:
1 string(字符串)
2 hash(哈希)
3 list(列表)
4 set(集合)
5 zset(sorted set:有序集合)
3.1 string
string 是 redis 最基本的类型,可以理解成与 Memcached 一模一样的类型,一个 key 对应一个value。
• string 类型是二进制安全的。redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
• string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB
• redis 127.0.0.1:6379> SET name ”keyman"
• redis 127.0.0.1:6379> GET name
应用场景
• String是最常用的一种数据类型,普通的key/value 存储都可以归为此类.即可以完全实现目前 Memcached 的功能,并且效率更高。还可以享受Redis的定时持久化,操作日志及 Replication等功能。除了提供与 Memcached 一样的get、set、incr、decr 等操作外
• Redis还提供了下面一些操作:
• 获取字符串长度
• 往字符串append内容
• 设置和获取字符串的某一段内容
• 设置及获取字符串的某一位(bit)
• 批量设置一系列字符串的内容
• 实现方式:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int
3.2 hash
常用命令
• hget,hset,hgetall 等
应用场景
• 在Memcached中,经常将一些结构化的信息打包成HashMap,在客户端序列化后存储为一个字符串的值,用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。
3.3 list
常用命令
• lpush、rpush、lpop、rpop、lrange
应用场景
• Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现。
• Lists 就是链表,相信略有数据结构知识的人都应该能理解其结构。使用Lists结构,可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,
• 可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行。
Redis还提供了操作Lists中某一段的api,可以直接查询,删除Lists中某一段的元素
3.4 set
常用命令
• sadd、spop、smembers、sunion 等
应用场景:
• Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
• Sets 集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,可以存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中
3.5 sort set
常用命令:
• zadd,zrange,zrem,zcard等
使用场景
• Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。
• 另外还可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行
四 redis持久化
Redis 是内存型数据库,为了保证数据在断电后不会丢失,需要将内存中的数据持久化到硬盘上。
Redis提供了两种持久化的方式
• RDB(Redis DataBase)
• AOF(Append Only File)
4.1 RDB
在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本。如果系统发生故障,将会丢失最后一次创建快照之后的数据。如果数据量大,保存快照的时间会很长。
4.2 AOF
换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。将写命令添加到 AOF 文件(append only file)末尾。
五 redis架构
5.1 单机
5.2 主从
5.3 哨兵
5.4 集群
5.3 哨兵
哨兵的出现主要是解决了主从复制出现故障时需要人为干预的问题。
哨兵主要功能
• 集群监控:负责监控Redis master和slave进程是否正常工作
• 消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
• 故障转移:如果master node挂掉了,会自动转移到slave node上
• 配置中心:如果故障转移发生了,通知client客户端新的master地址
5.4 集群
即使使用哨兵,redis每个实例也是全量存储,每个redis存储的内容都是完整的数据,浪费内存且有木桶效应。
为了最大化利用内存,可以采用集群,就是分布式存储。
即每台redis存储不同的内容,共有16384个slot。
每个redis分得一些slot,hash_slot = crc16(key) mod 16384 找到对应slot。
集群至少需要3主3从,且每个实例使用不同的配置文件,主从不用配置,集群会自己选。
• 高可用性:在主机挂掉后,自动故障转移,使前端服务对用户无影响。
• 读写分离:将主机读压力分流到从机上。
• 可在客户端组件上实现负载均衡,根据不同服务器的运行情况,分担不同比例的读请求压力
欢迎关注我的微信公众号"IT小Chen",共同学习,共同成长!!!