Redis 是什么
Redis (全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis 是一个NoSQL数据库,是一个运行在内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
在了解什么是 Redis 之前,先了解下什么是
NoSQL
NoSQL(
Not Only SQL
),意即不仅仅是 SQL, 泛指非关系型的数据库。Nosql 这个技术门类,早期就有人提出,发展至 2009 年趋势越发高涨。随着互联网网站的兴起,传统的关系数据库在应付动态网站,特别是超大规模和高并发的纯动态网站已经显得力不从心,暴露了很多难以克服的问题。如
商城网站中对商品数据频繁查询
、对热搜商品的排行统计
、订单超时问题
、以及微信朋友圈(音频,视频)存储等相关使用传统的关系型数据库实现就显得非常复杂,虽然能实现相应功能但是在性能上却不是那么乐观。nosql 这个技术门类的出现,更好的解决了这些问题,它告诉了世界不仅仅是 sql。
主流的理解有以下三种
1.key value store.是一个以key-value形式存储的数据库,定位直指MySQL,用来作为唯一的存储系统。
2.memory cache.是一个把数据存储在内存中的高速缓存,用来在应用和数据库间提供缓冲,替代memcachd。
3.data structrue server.把它支持对复杂数据结构的高速操作作为卖点,提供某些特殊业务场景的计算和展现需求。比如排行榜应用,Top 10之类的。
Redis 的特点
Redis 是一个开源(BSD 许可)的内存数据结构存储,用作数据库、缓存、消息代理和流引擎。Redis 提供[[Redis 的存储类型|数据结构]],如字符串、哈希、列表、集合、带范围查询的排序集合、位图、超日志、地理空间索引和流。Redis 具有内置复制、Lua 脚本、LRU 逐出、事务和不同级别的磁盘持久性,并通过 Redis Sentinel 和 Redis Cluster 自动分区提供高可用性。
Redis 将所有的数据都存放在内存中,所以它的读写性能十分惊人,用作数据库,缓存和消息代理。
Redis 典型的应用场景包括:缓存、排行榜、计数器、社交网络、消息队列等。
用户可以对这些类型运行原子操作,如附加到字符串;递增散列中的值;将元素推送到列表中;计算集合交集、并集和差集;或者获得排序集中排名最高的成员。
为了获得最佳性能,Redis 使用内存中的数据集。根据用户的使用情况,Redis 可以通过定期将数据集转储到磁盘或将每个命令附加到基于磁盘的日志来[[Redis 的持久化机制|持久化]]您的数据。如果只需要一个功能丰富、联网的内存缓存,也可以禁用持久性。
在业务快速增长时,单机的 Redis 也支撑不了业务,为此 Redis 也提供了[[Redis 的主从库模式以及主从复制|主从集群]]、[[Redis的哨兵机制以及集群|哨兵集群]]等高可用解决方案。
Redis 另外还支持:
- 事务
- 发布/订阅
- Lua 脚本
- 自动故障切换
Redis 的优势
- 性能极高 – Redis 能读的速度是 110000 次/s,写的速度是 81000 次/s 。
- 丰富的数据类型 – Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来。
- 丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性。
Redis 与其他 key-value 存储有什么不同?
- Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis 的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
- Redis 运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样 Redis 可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
Redis 的应用场景
1、缓存——热数据
这是 Redis 使用最多的场景。Redis 能够替代 Memcached,让你的缓存从只能存储数据变得能够更新数据,因此你不再需要每次都重新生成数据。
2、计数器
诸如统计点击数、转发数、评论数等应用。由于单线程,可以避免并发问题,保证不会出错,而且 100% 毫秒级性能!爽。 命令:INCRBY 当然爽完了,别忘记持久化,毕竟是 redis 只是存了内存!
3、消息队列
相当于消息系统,运行稳定并且快速,支持模式匹配,能够实时订阅与取消频道,和 ActiveMQ,RocketMQ 等工具类似,但是个人觉得简单用一下还行,如果对于数据一致性要求高的话还是用 RocketMQ 等专业系统。 由于 redis 把数据添加到队列是返回添加元素在队列的第几位,所以可以做判断用户是第几个访问这种业务 队列不仅可以把并发请求变成串行,并且还可以做队列或者栈使用
4、位操作(大数据处理)
用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。 腾讯 10 亿用户,要几毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个 key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多,腾讯光这个得多花多少钱。。)这里要用到位操作——使用 setbit、getbit、bitcount 命令。
原理是: redis 内构建一个足够长的数组,每个数组元素只能是 0 和 1 两个值,然后这个数组的下标 index 用来表示我们上面例子里面的用户 id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0 和 1)来构建一个记忆系统,上面我说的几个场景也就能够实现。用到的命令是:setbit、getbit、bitcount。
5、分布式锁与单线程机制
验证前端的重复请求(可以自由扩展类似情况),可以通过 redis 进行过滤:每次请求将 request Ip、参数、接口等 hash 作为 key 存储 redis(幂等性请求),设置多长时间有效期,然后下次请求过来的时候先在 redis 中检索有没有这个 key,进而验证是不是一定时间内过来的重复提交 秒杀系统,基于 redis 是单线程特征,防止出现数据库“爆破” 全局增量 ID 生成,类似“秒杀”
6、最新列表
例如新闻列表页面最新的新闻列表,如果总数量很大的情况下,尽量不要使用 select a from A limit 10 这种 low 货,尝试 redis 的 LPUSH 命令构建 List,一个个顺序都塞进去就可以啦。不过万一内存清掉了咋办?也简单,查询不到存储 key 的话,用 mysql 查询并且初始化一个 List 到 redis 中就好了。
7、排行榜
谁得分高谁排名往上。命令:ZADD(有续集,sorted set)