基础和应用

1.Redis是远程调用技术的首字母缩写。

2.Redis可以用来做什么?

  • Redis可以用来做缓存。

  • 分布式锁

3.Redis的应用举例

  • 记录帖子的点赞数、评论数和点击数。(使用HASH)

  • 记录用户的帖子ID列表,便于快速显示用户的帖子列表。(ZSET)

  • 记录帖子的标题、摘要、作者和封面信息,用于展示。(hash)

  • 记录帖子的点怎用户ID和列表ID,用于显示和去重计数。(zset)

  • 缓存近期热帖内容,减少数据库压力。(hash)

  • 记录帖子相关文章ID,根据内容推荐相关帖子。(list)

  • 如图帖子是正数递增,可以使用Redis来分配帖子ID。(计数器)

  • 收藏集合帖子的之前的关系。(zset)

  • 记录热榜的 ID列表、总热榜和分类榜

  • 缓存用户行为的历史,过滤恶意行为(zset、hash)

Redis安装

Redis安装可以在window、linux中安装,也可以使用docker安装。

  • Docker安装方式

    拉取镜像
    docker pull redis
    运行容器
    docker run --name myredis -d -p 6379:6379 redis
    后台执行
    docker exec -it myredis redis-cli
  • github源码安装

    git clone 
    cd redis
    编译
    make
    cd src
    运行服务
    ./redis-server --deamonize yes
    运行客户端
    ./redis-cli
  • apt-get install /yum install /brew install

yum install redis
redis-cli

5种基本的数据结构

Redis的数据结构,分为string、list、hash、set、zset

string

  • 它的内部是一个字符串数组,使用一个唯一的key作为字符串名称的,通过key获取数据。不同的值在于他们value的值不同。

  • 字符串一般可以使用在缓存,将用户信息序列化之后放入字符串中。

  • 实现原理:类似于Arraylist,使用阈值的方式开辟空间,一般会加倍,但是当数据大于1M的时候,每次加1M,最大的值是512M.

  • 基本操作

    • 键值对

      test:0>set name value01
      "OK"
      test:0>get name
      "value01"
      test:0>exsits name
      "ERR unknown command 'exsits'"
      test:0>exists name
      "1"
      test:0>del name
      "1"
      test:0>get name
      null
      test:0>
    • 批量键值对

      test:0>set name1 value01
      "OK"
      test:0>set name2 value02
      "OK"
      test:0>mget name1 name2
      1)  "value01"
      2)  "value02"
      test:0>mset name1 kangwang name2 jiangyu name3 yjh
      "OK"
      test:0>mget name1 name2 name3
      1)  "kangwang"
      2)  "jiangyu"
      3)  "yjh"
      test:0>
    • 过期和set指令的扩展

      test:0>set name kangwang
      "OK"
      test:0>expire name 5
      "1"
      test:0>get name
      null
      ---------------
      test:0>setex name 5 code
      "OK"
      test:0>get name
      null
      -----------------
      test:0>setnx name kkkk
      "1"
      test:0>setnx name kkkk
      "0"
    • 计数

      test:0>set age 39
      "OK"
      test:0>incr age
      "40"
      test:0>incrby age 5
      "45"

list

类似于java的linkList,他是链表不是数组。他可以作为消息队列

  • 队列

test:0>lpush books java c++ c python
"4"
test:0>llen books
"4"
test:0>lpush books java c++ c python
"4"
test:0>llen books
"4"
test:0>rpop books
"java"
  • 堆栈

左边入,左边出
  • 角标获取数据

test:0>lindex books 0
"python"
test:0>lrange books 0 -1
1) "python"
2) "c"
3) "c++"
test:0>
  • 快速列表

Redis底层使用的是一个快速列表,在数据小的时候,将数据存储在一块练习的内存中。当数据比较多的时候,普通链表太浪费空间,所以它将多个内存块的数据使用链表连接起来。

Hash

典相当于java的HashMap,无序的字典,内部结构和HashMap类似。不同之处:

Redis字典相当于java的HashMap,无序的字典,内部结构和HashMap类似。不同之处:

  • Redis只会是字符串。,并且hash的方式也不一样。

  • java会一次的进行hash,但是redis会慢慢的进行hash,他会保存两个hash结构,然后在后续定时任务以及其他操作的时候,逐渐的进行迁移,当最后一个节点移动完毕的时候,就会将其取而代之。

  • hash可以存储用户的信息,字符串会一次的进行序列化,并且会将所有的数据读取。浪费带宽。

Set

Redis相当于hashSet,内部的建是无序的、唯一的。当最后一个数据删除,数据就会自己的删除,可以进行去重保证一次不会出现两次的数据。

test:0>sadd stu s1
"1"
test:0>sadd stu s2
"1"
test:0>smembers stu
1)  "s2"
2)  "s1"
test:0>sadd stu s
"1"
test:0>smembers stu
1)  "s"
2)  "s2"
3)  "s1"

顺序也是不一致的。

其他操作

是否存在数据
test:0>sismember stu s
"1"
数据的长度
test:0>scard stu
"3"
弹出
test:0>spop stu
"s2"

zset

有序列表,它类似于sorted和HashMap,set保证唯一,Sort保证有序。最后一个数据撒喊出,那么数据结构也会删除。可以用来存储,评论和点赞。

通用规则

list、set、hash、zset如果不存在就会创建,再操作。没有数据了就删除了。

过期时间

过期他是一个对象进行过期,不是某一个元素,也不是key、如果设置了过期时间,在对其进行修改,就会将其过期时间删除。

线程IO模型

Redis是一个单线程的程序,nginx、nodejs都是单线程的。但是他也很快,这是因为数据都在内存中,计算是内存级别的。在处理O(n)的指令就会出现卡顿的问题。

Redis为什么可以处理多个客户端,这是因为它采用多路复用。

非阻塞IO

默认读写是阻塞的,最后可以是一个n,这个参数由套接字传递的,如果没有数据就不糊会返回,卡在哪里。直到有数据或者是断开连接,才会返回或者是继续处理。读的时候,只有放写满了才会阻塞。当有非堵塞的时候,就会出现一个问题,怎样就写完了,怎样就读完了,如果读不完怎么办。这个通过轮询来进行处理这个问题。

多路复用

最简单的时间轮询API Select函数,提供给用户的API.输入是read_fds和write_fds.输出是对应的可读事件,提供一个timeout.没有任何事件的时候,等timeout就会进入堵塞,有事件来就会返回。拿到事件就会进行轮询,进入一个死循环。

指令队列

Redis会将每一个客户端套接字都关联一个指令队列,通过队列来执行任务,先到先服务。

服务队列

同时提供一个响应队列,Redis通过队列将返回结果返回给客户端,为null,就不去获取写事件了。将客户端描述符拿出来。当队列有数据了在进行获取。

定时任务

单线程的任务,如果在一个IO上堵塞,那么定时任务到时怎么办?Redis的计时放在一个堆中,将快要执行的任务放在最上面,每一个循环周期中,Redis都会对最小堆里面已经到时的进行处理,将快要执行的任务时间记下来,这个值是select的timeout。在这个时间可以安心睡了。

持久化

Redis数据存储在内存中,宕机就会消失,那么就可以使用一种策略,让其可以一种存在,第一种使用快照;第二种使用AOF日志。但是有个问题,AOF的增大,启动会变慢。快照是存在一个紧凑的二进制文件中。

快照原理

Redis是单线程,他需要执行多个客户端的操作。如果需要快照,那么就需要一边服务一边进行IO快照。并且IO操作不可以多路复用。

问题:快照的同时,数据还在改变,这怎么办。

Redis使用的是WOW(copy on write)

fork

持久化会调用glibc函数fork产生一个子进程,快照持久化完全交给子进程来处理,父进程继续响应客户端。

在子进程进行数据持久化的时候,不会修改现有数据的内存数据结构,仅仅只是循环,将数据持久化到内存中。父进程对客户端进行处理,不断修改。

Copy on write在复制上写,将数据段复制一个,然后在上面进行修改。

AOF原理

AOF存储的是Redis服务器执行的指令,仅仅记录了修改的指令。

AOF的流程为:收到指令,先对指令进行效验、逻辑处理,没有问题,就会立即将文本指令存储到AOF日志中先执行,在写入日志

AOF日志过大之后,需要对其进行瘦身处理。

AOF日志重写

Redis提供了bgrewriteaof指令进行瘦身,原理是:开辟一个新的子进程对内存进行遍历,转化为一系列的指令,将指令放入到新的一个日志中,再将执行期间的日志追加,然后将旧的日志替换掉。瘦身就算结束了。

fsyns

aof日志的形式放在内存中,但是aof读写的时候,先将数据放入内存中,然后在刷到磁盘。

Redis原理(一)的更多相关文章

  1. Redis原理与实践总结

    Redis原理与实践总结 本文主要对Redis的设计和实现原理做了一个介绍很总结,有些东西我也介绍的不是很详细准确,尽量在自己的理解范围内把一些知识点和关键性技术做一个描述.如有错误,还望见谅,欢迎指 ...

  2. Redis原理篇

    Redis原理篇 1.发布 订阅模式 1.1列表 的局限 ​ 前面我们说通过队列的 rpush 和 lpop 可以实现消息队列(队尾进队头出),但是消费者需要不停地调用 lpop 查看 List 中是 ...

  3. Redis 系列(04-2)Redis原理 - 内存回收

    目录 Redis 系列(04-2)Redis原理 - 内存回收 Redis 系列目录 1. 过期策略 1.1 定时过期(主动淘汰) 1.2 惰性过期(被动淘汰) 1.3 定期过期 2. 淘汰策略 2. ...

  4. Redis原理详解

    Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...

  5. 面试被吊打系列 - Redis原理

    小张兴冲冲去面试,结果被面试官吊打! 小张: 面试官,你好.我是来参加面试的. 面试官: 你好,小张.我看了你的简历,熟练掌握Redis,那么我就随便问你几个Redis相关的问题吧.首先我的问题是,R ...

  6. redis原理分析

    基本全是参考http://blog.csdn.net/a600423444/article/details/8944601     redis的使用大家都很熟悉,可能除了watch 锁,pipelin ...

  7. Redis原理及使用

    一:原理介绍 1:什么是redis?  Redis 是一个基于内存的高性能key-value数据库. 2:Reids的特点Redis本质上是一个Key-Value类型的内存数据库,很像memcache ...

  8. Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)

    一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...

  9. redis原理及实现

    1 什么是redis redis是nosql(也是个巨大的map) 单线程,但是可处理1秒10w的并发(数据都在内存中) 使用java对redis进行操作类似jdbc接口标准对mysql,有各类实现他 ...

  10. Redis原理及集群相关知识

    读书笔记 <Redis开发与运维 > Redis使用场景 作为缓存层 减少对Mysql的压力 计数功能 比如使用原子命令incr 共享Session 设置过期时间 可以限制短信接口等调用 ...

随机推荐

  1. 使用powerdesigner建模时设置主键自增的问题

    研究了一下,其实只要双击表,选择columns,再双击在你所要设为自增型的键上(比如你的id)或者右键选择Properties,弹出一个ColumnProperties 对话框,我们看到有标识 ide ...

  2. 数据库更新DATE类型的时间

    使用to_date() 进行格式转换 to_date('2018/11/16','yyyy/MM/dd') update tableName t set t.shipment_date = to_da ...

  3. 洛谷 P1964 【mc生存】卖东西

    P1964 [mc生存]卖东西 题目背景 服务器好好玩 题目描述 lcy0x1去服务器的系统商店卖东西. 一个人的背包有21格. 一开始他的背包里有m件不同的物品(不能卖). 他要卖n种物品,每种物品 ...

  4. 使用表单向action提交时出现 “Error setting expression 'button' with value……”

    原因是,form中的组件设置了name属性,struts2会通过OGNL在action中找相应的属性. 如 <form action="login"> <intp ...

  5. [Python] Format Strings in Python

    Single quotes and double quotes can both be used to declare strings in Python. You can even use trip ...

  6. Reuse Is About People and Education, Not Just Architecture

     Reuse Is About People and Education, Not Just Architecture Jeremy Meyer you MigHT AdopT THE AppRoA ...

  7. ubuntu adb 安装

    ubuntu 下adb 安装,其实就是下载一个adb,然后给它赋予可执行权限,最后在环境变量里添加一下罢了.具体如下 1.下载adb 这个工具其实是在sdk工具包里面的platform-tools文件 ...

  8. javascript 将时间戳格式化

    <script>function getLocalTime(nS) { return new Date(parseInt(nS) * 1000).toLocaleString().repl ...

  9. RTSP、HTTP、HTTPS、SDP四种协议详解

    我们将主要讲解RTSP,HTTP,HTTPS, SDP四种协议.  一:RTSP协议简介 实时流协议RTSP是一个应用层协议,用于控制具有实时特性的数据(例如多媒体流)的传送. RTSP协议一般与RT ...

  10. js --- for in 和 for of

    前言:for of是ES6新增的循环方法.前面已经说到了 [JavaScript]for.forEach .for in.each循环详解.那for of又是怎么使用的? 一.使用例子 使用例子(一) ...