一:Redis 概述

  - Redis 是内存级别的数据库,在一台普通电脑上,Redis 3.X 便可以读取 10 万个键值对(现在的Redis官方版本已经更新到了5.X,性能会更好)。

二:关于Redis 和 Memcached 的性能问题。

  - 理论上 Memcached 为多线程模型,会比 Redis 性能好。

  - 但是,Redis的性能已经足够好,在大部分场合下性能都不会成为它的瓶颈。

  - 我们更应该关注的是 Redis 和 Memcached 的应用场景。

三:key 键名设计

  - 可读性和可管理性 

    -  以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id

  - 简洁性

    - 保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视,如:( user:{uid}:friends:messages:{mid}简化为u:{uid}:fr:m:{mid} )

  - 不要包含特殊字符

    - 空格、换行、单双引号以及其他转义字符 等

四:value设计

  -  不要使用特别大的键(bigkey)

    - 虽然 Redis 官方说明了 key和string类型value限制均为512MB。

    - 但是防止网卡流量、慢查询,string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000。

  -  非字符串的bigkey,不要使用del删除,使用hscan、sscan、zscan方式渐进式删除

    - 同时要注意防止bigkey过期自动删除问题(例如一个200万的zset设置1小时过期,会触发del操作,造成阻塞。

    - 而且该操作不会不出现在慢查询中(latency可查)),查找方法和删除方法。

  - 选择适合的数据类型

    - 取代将数据存储为数千(或者数百万)独立的字符串,可以考虑使用哈希数据结构将相关数据进行分组。哈希表是非常有效率的,并且可以减少你的内存使用;

    - 同时,哈希还更有益于细节抽象和代码可读。

    - 合适时候,使用list代替set。如果你不需要使用set特性,List在使用更少内存的情况下可以提供比set更快的速度。

    - Sorted sets是最昂贵的数据结构,不管是内存消耗还是基本操作的复杂性。

      - 如果你只是需要一个查询记录的途径,并不在意排序这样的属性,那么建议使用哈希表

  - 控制key的生命周期

    - Redis不是垃圾桶,建议使用expire设置过期时间(条件允许可以打散过期时间,防止集中过期)。

    - 不过期的数据重点关注idletime。

 

五:命令使用

  -  O(N)命令关注N的数量

    - hgetall、lrange、smembers、zrange、sinter等并非不能使用,但是需要明确N的值。

    - 在N值过大时候,有遍历的需求可以使用hscan、sscan、zscan代替。

  - 禁用命令

    -  keys

      -  客户端可查询出所有存在的键。(键太多导致Redis崩溃,缓存被穿透)

    -  flushdb

      -  删除当前所选数据库的所有键。此命令永远不会失败。

    -  flushall

      -  删除所有现有数据库的所有键,而不仅仅是当前选定的数据库。此命令永远不会失败。

    - 禁止线上使用keys、flushall、flushdb等,通过redis的rename机制禁掉命令,或者使用scan的方式渐进式处理。

  

  - 使用批量操作提高效率

    - 原生命令:例如mget、mset。

      - 非原生命令:可以使用pipeline提高效率。   

      - 两者不同:

          - 原生是原子操作,pipeline是非原子操作。
        - pipeline可以打包不同的命令,原生做不到
        - pipeline需要客户端和服务端同时支持。
 
  

  - 不建议过多使用Redis事务功能

    - Redis的事务功能较弱(不支持回滚),而且集群版本(自研和官方)要求一次事务操作的key必须在一个slot上(可以使用hashtag功能解决)。

 

  - monitor命令

    - 必要情况下使用monitor命令时,要注意不要长时间使用。

六:设置合理的淘汰策略

  - 根据自身业务类型,选好maxmemory-policy(最大内存淘汰策略),设置好过期时间。

  - 默认策略是volatile-lru,即超过最大内存后,在过期键中使用lru算法进行key的剔除,保证不过期数据不被删除,但是可能会出现OOM问题(申请内存过大导致自杀)。

  - 具体

    - 

    - allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。

    - allkeys-random:随机删除所有键,直到腾出足够空间为止。

    - volatile-random:随机删除过期键,直到腾出足够空间为止。

    - volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略。

    - noeviction:不会剔除任何数据,拒绝所有写入操作并返回客户端错误信息"(error) OOM command not allowed when used memory",此时Redis只响应读操作。

《Redis 使用规范》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 简单对比git pull和git pull --rebase的使用

    使用下面的关系区别这两个操作:git pull = git fetch + git mergegit pull --rebase = git fetch + git rebase 现在来看看git m ...

  2. 机器学习爱好者 -- 翻译吴恩达老师的机器学习课程字幕 http://www.ai-start.com/

    机器学习爱好者 -- 翻译吴恩达老师的机器学习课程字幕 GNU Octave    开源  MatLab http://www.ai-start.com/ https://zhuanlan.zhihu ...

  3. 史上最明白的 NULL、0、nullptr 区别分析(老师讲N篇都没讲明白的东东),今天终于明白了,如果和我一样以前不明白的可以好好的看看...

    C的NULL 在C语言中,我们使用NULL表示空指针,也就是我们可以写如下代码: int *i = NULL; foo_t *f = NULL; 实际上在C语言中,NULL通常被定义为如下: #def ...

  4. @Transactional 无效原因

    在controller 上面使用  @Transactional 注解时候发现数据没有回滚,在执行完update 更新语句,事务直接就commit 了, 此时方法尚未执行结束,数据库数据已经更新了. ...

  5. UiAutomator1.0 与 UiAutomator2.0

      在使用2.0之前,对android自动化框架也做过一些了解<Android 自动化测试框架>.使用UiAutomator2.0也有一段时间,这里将1.0与2.0进行一个对比总结. Ui ...

  6. 【C++ Primer | 09】容器适配器

    一.stack s.push(): 向栈内压入一个成员: s.pop(): 从栈顶弹出一个成员: s.empty(): 如果栈为空返回true,否则返回false: s.top(): 返回栈顶,但不删 ...

  7. hibernate 保存报错 Hibernate operation: could not get next sequence value;

    错误信息: [2017-09-28 18:51:38,854]-[org.hibernate.util.JDBCExceptionReporter:101] ERROR - Numeric Overf ...

  8. Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第九集-补充-之安装mariadb】

    由于也是第一次安装,再此不必献丑了,贴上参考链接: 1,指导我为什么使用mariadb而不是用mysql:https://blog.csdn.net/liumiaocn/article/details ...

  9. 关于postman各功能的说明及用法以及批量执行

    这玩意功能还不错,可以学学,在测试接口或者配合写代码测接口时是有帮助作用的.今天也去打听了一下,一下我就做了一下记录. 首先,主界面: 分开记录,写的详细一些. 左侧菜单栏: 主菜单(请求部分); 输 ...

  10. forEach循环

    一.语法 var myArr=['camille','2020','vas','en','France']; // 1.只输出元素,传一个参数 myArr.forEach(function (ele) ...