https://blog.csdn.net/u014229282/article/details/81174202

最近阅读了《redis设计与实现》,这是一本比较枯燥的书,毕竟涉及到redis底层数据结构。我写本文章的目的,主要围绕redis设计与实现这本书整体的一个印象,然后梳理了这本书整体思路:

为什么要选择Redis:介绍Redis的使用场景与使用Redis的原因;
    Redis常用命令总结:包括时间复杂度总结与具体数据类型在Redis内部使用的数据结构;
    Redis的高级功能:包括持久化、复制、哨兵、集群介绍;
    理解Redis:理解内存、阻塞;这部分是非常重要的,前面介绍的都可以成为术,这里应该属于道的部分;
    开发技巧:主要是一些开发实战的总结,包括缓存设计与常见坑点。

本篇文章主要还是讲redis能做什么,为什么能做这些?

背景

在面试的时候,常被问比较下Redis与Memcache的优缺点,个人觉得这二者并不适合一起比较,一个是非关系型数据库不仅可以做缓存还能干其它事情,一个是仅用做缓存。常常让我们对这二者进行比较,主要也是由于Redis最广泛的应用场景就是Cache。那么Redis到底能干什么?又不能干什么呢?

注:笔者会在以后的文章来分析Redis与Memcache的优缺点。

Redis能做什么

缓存,毫无疑问这是Redis当今最为人熟知的使用场景。再提升服务器性能方面非常有效;

排行榜,如果使用传统的关系型数据库来做这个事儿,非常的麻烦,而利用Redis的SortSet数据结构能够非常方便搞定;

计算器/限速器,利用Redis中原子性的自增操作,我们可以统计类似用户点赞数、用户访问数等,这类操作如果用MySQL,频繁的读写会带来相当大的压力;限速器比较典型的使用场景是限制某个用户访问某个API的频率,常用的有抢购时,防止用户疯狂点击带来不必要的压力;

注:限速器也是对请求限流的一种实现方式。

好友关系,利用集合的一些命令,比如求交集、并集、差集等。可以方便搞定一些共同好友、共同爱好之类的功能;

简单消息队列,除了Redis自身的发布/订阅模式,我们也可以利用List来实现一个队列机制,比如:到货通知、邮件发送之类的需求,不需要高可靠,但是会带来非常大的DB压力,完全可以用List来完成异步解耦;

Session共享,默认Session是保存在服务器的文件中,即当前服务器,如果是集群服务,同一个用户过来可能落在不同机器上,这就会导致用户频繁登陆;采用Redis保存Session后,无论用户落在那台机器上都能够获取到对应的Session信息。

注:对于基于Redis实现分布式session 笔者会在以后文章接入说明

Redis不能做什么

Redis感觉能干的事情特别多,但它不是万能的,合适的地方用它事半功倍。如果滥用可能导致系统的不稳定、成本增高等问题。

比如,用Redis去保存用户的基本信息,虽然它能够支持持久化,但是它的持久化方案并不能保证数据绝对的落地,并且还可能带来Redis性能下降,因为持久化太过频繁会增大Redis服务的压力。

简单总结就是数据量太大、数据访问频率非常低的业务都不适合使用Redis。

数据太大会增加成本,访问频率太低,保存在内存中纯属浪费资源。如果不担心浪费资源,那请忽略。

Redis为什么能做这些

上面说了Redis的一些使用场景,那么这些场景的解决方案也有很多其它选择,比如缓存可以用Memcache,Session共享还能用MySql来实现,消息队列可以用RabbitMQ,我们为什么一定要用Redis呢?

那是因为Redis执行速度快:

速度快,完全基于内存;
    使用C语言实现,网络层使用epoll解决高并发问题;
    单线程模型避免了不必要的上下文切换及竞争条件;

注意:单线程仅仅是说在网络请求这一模块上用一个请求处理客户端的请求,像持久化它就会重开一个线程/进程去进行处理

丰富的数据类型;

Redis有8种数据类型,当然常用的主要是 String、Hash、List、Set、 SortSet 这5种类型(还有Bitmaps-位图、HyperLogLog、GEO-地理信息定位),他们都是基于键值的方式组织数据。每一种数据类型提供了非常丰富的操作命令,可以满足绝大部分需求,如果有特殊需求还能自己通过 lua 脚本自己创建新的命令(具备原子性);

除了提供的丰富的数据类型,Redis还提供了像慢查询分析、性能测试、Pipeline、事务、Lua自定义命令、Bitmaps、HyperLogLog、发布/订阅、Geo等个性化功能。

Redis的代码开源在GitHub,代码非常简单优雅,任何人都能够吃透它的源码;它的编译安装也是非常的简单,没有任何的系统依赖;有非常活跃的社区,各种客户端的语言支持也是非常完善。另外它还支持事务(没用过)、持久化、主从复制让高可用、分布式成为可能。

做为一个开发者,对于我们使用的东西不能让它成为一个黑盒子,我们应该深入进去,对它更了解、更熟悉。

总结Redis特性

速度快

数据存放在内存中;单线程模式,避免了线程上下文切换及多线程竞争访问;c语言实现,更容易接近系统api;采用epoll非阻塞IO,不在网络上浪费时间;

支持多种数据类型

支持8种数据类型:String、Hash、List、Set、 SortSet、Bitmaps、HyperLogLog、GEO;

功能丰富

丰富的API,如可设置键过期,存在即设置(这可以用来解决分布式锁问题),基于发布订阅可实现简单的消息队列,通过Lua创建新命令,具有原子性,管道(pipeline)功能,解决网络开销;

服务器简单

开源代码优雅,容易阅读源码,采用单线程模型,避免并发问题,redis自己实现了多路复用;

客户端语言版本多

如Java、Php、Go

支持多种持久化方式

RDB和AOP,这两种持久化深入分析请看:https://blog.csdn.net/u014229282/article/details/81121214

支持集群部署

支持主从复制,高可用集群,内部集群方式与Memcache做集群实现不一样的机制。

本文章来源:https://github.com/Zeb-D/my-review

原文:https://blog.csdn.net/u014229282/article/details/81174202

Redis能做什么?不能做什么?的更多相关文章

  1. redis、memcache、mongoDB 做了对比

    from: http://yang.u85.us/memcache_redis_mongodb.pdf   从以下几个维度,对redis.memcache.mongoDB 做了对比. 1.性能 都比较 ...

  2. 游戏引擎网络开发者的64做与不做(二A):协议与API

    [编者按]在这个系列之前的文章"游戏引擎网络开发者的64做与不做(一):客户端方面"中,Sergey介绍了游戏引擎添加网络支持时在客户端方面的注意点.本文,Sergey则将结合实战 ...

  3. 游戏引擎网络开发者的 64 做与不做 | Part 1 | 客户端方面

    摘要:纵观过去 10 年的游戏领域,单机向网络发展已成为一个非常大的趋势.然而,为游戏添加网络支持的过程中往往存在着大量挑战,这里将为大家揭示游戏引擎网络开发者的 64 个做与不做. [编者按]时下, ...

  4. 产品相关 做产品VS做项目

    做产品VS做项目 by:授客 QQ:1033553122 相关定义 根据GB/T19000—2008<质量管理体系基础和术语>,有以下定义 过程process 一组将输入转化为输出的相互关 ...

  5. 子查询 做where条件 做 from的临时表 ,做select的一个字段 等

    子查询 做where条件 做 from的临时表 ,做select的一个字段 等

  6. Redis集群方案怎么做?大牛给你介绍五种方案!

    Redis集群方案 Redis数据量日益增大,而且使用的公司越来越多,不仅用于做缓存,同时趋向于存储这块,这样必促使集群的发展,各个公司也在收集适合自己的集群方案,目前行业用的比较多的是下面几种集群架 ...

  7. Redis集群方案怎么做?

    转载自:https://www.jianshu.com/p/1ecbd1a88924 Redis集群方案 Redis数据量日益增大,而且使用的公司越来越多,不仅用于做缓存,同时趋向于存储这块,这样必促 ...

  8. 安装过redis集群,重新做集群办法:

    二:找到问题:这个地方IP的问题,以上是正确的版本,以前有问题的版本的Ip是127.0.0.1, 原因是这个地方以前我没注释redis.conf文件中的bind 127.0.0.1 然后做集群时使用的 ...

  9. 三分钟学会Redis在.NET Core中做缓存中间件

    大家好,今天给大家说明如何在.NET Core中使用Redis,我们在想要辩论程序的好与坏,都想需要一个可视化工具,我经常使用的是一位国内大牛开发的免费工具,其Github地址为: https://g ...

  10. Redis和MemCache静态Map做缓存区别

    本地缓存和分布式缓存 本地缓存:使用自带的map或者guava实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着jvm的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不 ...

随机推荐

  1. CF练习记录

    2018/5/6 Codeforces Round #478 (Div. 2) C http://codeforces.com/contest/975/problem/C Valhalla Siege ...

  2. LeetCode-环形链表II

    LeetCode-环形链表II 为找到入口点可以用以下方法 使用快慢指针法直到两个指针相遇 头节点处创建一个新的指针,并且向前移动,两个指针相遇处创建一个新的指针,并且向前移动,直到两个指针相遇为入口 ...

  3. Ansible自动化配置详解

    第1章 Ansible基本概述 1.1 ansible是一个配置管理系统configuration management system, 你只需要可以使用ssh访问你的服务器或设备就行. 1.安装软件 ...

  4. keepalived入门

    简介 Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服 ...

  5. phpredis命令

    <?php //redis //检查一个扩展是否已经加载.大小写不敏感. if (!function_exists('redis')) { echo '不支持 redis'; return ; ...

  6. python3 练习题100例 (二十六)回文数判断

    题目内容: 给一个5位数,判断它是不是回文数,是则输出yes,不是则输出no. 例如12321是回文数,它的个位与万位相同,十位与千位相同. 输入格式: 共一行,为一个5位数. 输出格式: 共一行,y ...

  7. print(__file__)返回<encoding error>的问题

    今天写了一下代码,本来是想得到当前文件的上面三层的目录的,结果返回的却是错误 import os import sys print(__file__) # 得到上上层目录的路径之后,加入到默认的环境变 ...

  8. C语言实例解析精粹学习笔记——30

    实例30: 用已知字符串s中的字符,生成由其中n个字符组成的所有字符排列.设n小于字符串s的字符个数,其中s中的字符在每个排列中最多出现一次.例如,对于s[]="abc",n=2, ...

  9. Qt——信号与槽

    自定义槽函数,槽函数可以是任何位置定义的函数(成员函数,静态函数,全局函数),但是槽函数的函数类型要和信号的函数类型一致.

  10. 详解mysql体系结构和存储引擎

    概述 之前整理的一些mysql方面内容,适合做备忘,因为我基本不会去记这些概念性的东西,大家做个了解就可以了. 一.定义数据库和实例 1.数据库: 物理操作系统文件或其他形式文件类型的集合. 在MyS ...