[toc]

缓存数据库的概念

  • 传统的数据库管理系统把所有数据都放在磁盘上进行管理,所以称做磁盘数据库(DRDB:Disk-Resident Database)。磁盘数据库需要频繁地访问磁盘来进行数据的操作,由于对磁盘读写数据的操作一方面要进行磁头的机械移动,另一方面受到系统调用(通常通过CPU中断完成,受到CPU时钟周期的制约)时间的影响,当数据量很大,操作频繁且复杂时,就会暴露出很多问题。
  • 近年来,内存容量不断提高,价格不断下跌,操作系统已经可以支持更大的地址空间(计算机进入了64位时代),同时对数据库系统实时响应能力要求日益提高,充分利用内存技术提升数据库性能成为一个热点。
  • 在数据库技术中,目前主要有两种方法来使用大量的内存。一种是在传统的数据库中,增大缓冲池,将一个事务所涉及的数据都放在缓冲池中,组织成相应的数据结构来进行查询和更新处理,也就是常说的共享内存技术,这种方法优化的主要目标是最小化磁盘访问。另一种就是内存数据库(MMDB:Main Memory Database,也叫主存数据库)技术,就是干脆重新设计一种数据库管理系统,对查询处理、并发控制与恢复的算法和数据结构进行重新设计,以更有效地使用CPU周期和内存,这种技术近乎把整个数据库放进内存中,因而会产生一些根本性的变化。
  • 内存数据库系统带来的优越性能不仅仅在于对内存读写比对磁盘读写快上,更重要的是,从根本上抛弃了磁盘数据管理的许多传统方式,基于全部数据都在内存中管理进行了新的体系结构的设计,并且在数据缓存、快速算法、并行操作方面也进行了相应的改进,从而使数据处理速度一般比传统数据库的数据处理速度快很多,一般都在10倍以上,理想情况甚至可以达到1000倍。
  • 而使用共享内存技术的实时系统和使用内存数据库相比有很多不足,由于优化的目标仍然集中在最小化磁盘访问上,很难满足完整的数据库管理的要求,设计的非标准化和软件的专用性造成可伸缩性、可用性和系统的效率都非常低,对于快速部署和简化维护都是不利的。

内存数据库历史和发展

雏形期

从上个世纪60年代末到80年代初。在这个时期中,出现了主存数据库的雏形。1969年IBM公司研制了世界上最早的数据库管理系统——基于层次模型的数据库管理系统IMS,并作为商品化软件投入市场。在设计IMS时,IBM考虑到基于内存的数据管理方法,相应推出了IMS/VS Fast Path。Fast Path是一个支持内存驻留数据的商业化数据库,但它同时也可以很好地支持磁盘驻留数据。在这个产品中体现了主存数据库的主要设计思想,也就是将需要频繁访问,要求高响应速度的数据直接存放在物理内存中访问和管理。在这个阶段中,包括网状数据库、关系数据库等其他各种数据库技术也都逐渐成型。

技术理论成熟期

1984 年,D J DeWitt 等人发表了《主存数据库系统的实现技术》一文。第一次提出了 Main Memory Database(主存数据库)的概念。预言当时异常昂贵的计算机主存价格一定会下降,用户有可能将大容量的数据库全部保存在主存中,提出了 AVL 树、哈希算法、主存数据库恢复机制等主存数据库技术的关键理论,为主存数据库发展指出了明确的方向 。

1984 年,D J DeWitt 等人提出使用非易逝内存或预提交和成组提交技术作为主存数据库的提交处理方案,使用指针实现主存数据库的存取访问。

1985 年,IBM 推出了 IBM 370 上运行的 OBE 主存数据库。

1986 年,RB Hagman 提出了使用检查点技术实现主存数据库的恢复机制。威斯康星大学提出了按区双向锁定模式解决主存数据库中的并发控制问题。并设计出 MM-DBMS 主存数据库。贝尔实验室推出了 DALI 主存数据库模型。

1987 年,ACM SIGMOD 会议中提出了以堆文件(HEAP FILE)作为主存数据库的数据存储结构。SouthernMethodist 大学设计出 MARS 主存数据库模型。

1988 年普林斯顿大学设计出 TPK 主存数据库。

1990 年普林斯顿大学又设计出 System M 主存数据库。

产品发展期和市场成长期

随着互联网的发展,越来越多的网络应用系统需要能够支持大用户量并发访问、高响应速度的的数据库系统,主存数据库市场成熟半导体技术快速发展,半导体内存大规模生产,动态随机存取存储器(DRAM)的容量越来越大,而价格越来越低,这无疑为计算机内存的不断扩大提供了硬件基础,使得主存数据库的技术可行性逐步成熟

1994年美国OSE公司推出了第一个商业化的,开始实际应用的主存数据库产品Polyhedra

1998年德国SoftwareAG推出了Tamino Database。

1999年日本UBIT会社开发出XDB主存数据库产品。韩国Altibase推出Altibase。

2000年奥地利的QuiLogic公司推出了SQL-IMDB。

2001年美国McObject推出eXtremeDB。加拿大Empress公司推出EmpressDB。

几种存技术应用的比较

第一代:用户定制的主存数据库。通过应用程序来管理内存和数据;不支持SQL语句, 不提供本地存储, 没有数据库恢复技术;性能好但很难维护和在别的应用中不能使用;应用在实时领域比如工厂自动化生产。

第二代:简单功能的内存数据库。能够快速处理简单的查询;支持部分的 SQL语句和简单的恢复技术;主要目的是能够快速处理大量事务;针对简单事务处理领域,尤其是交换机, 移动通信等。

第三代:通用的主存数据库。针对传统的商业关系型数据库领域,能够提供更高的性能、通用性以及稳定性;提供不同的接口来处理复杂的SQL语句和满足不同的应用领域;可以应用在计费、电子商务、在线安全领域,几乎包括磁盘数据库的所有应用领域。

几种企业中常用的缓存数据库比较

  • Memcached

    • Memcached简介
      1. Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。
      2. Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。
      3. Memcached是一种基于内存的key-value存储,用来存储小块的任意数据(字符串、对象)。这些数据可以是数据库调用、API调用或者是页面渲染的结果。
      4. Memcached简洁而强大。它的简洁设计便于快速开发,减轻开发难度,解决了大数据量缓存的很多问题。它的API兼容大部分流行的开发语言。
      5. 本质上,它是一个简洁的key-value存储系统,一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
    • Memcached优缺点
      • 优点:高性能读写、单一数据类型、支持客户端式分布式集群、一致性hash多核结构、多线程读写性能高。
      • 缺点:无持久化、节点故障可能出现缓存穿透、分布式需要客户端实现、跨机房数据同步困难、架构扩容复杂度高。
  • Redis

    • Redis简介
      1. Redis是一款开源的,ANSI C语言编写的,高级键值(key-value)缓存和支持永久存储NoSQL数据库产品。
      2. Redis采用内存(In-Memory)数据集(DataSet) 。
      3. 支持多种数据类型。
      4. 运行于大多数POSIX系统,如Linux、*BSD、OS X等。
      5. redis就是非关系型数据库的一种,存储方式是:key:value
    • Redis优缺点
      • 优点:高性能读写、多数据类型支持、数据持久化、高可用架构、支持自定义虚拟内存、支持分布式分片集群、单线程读写性能极高。
      • 缺点:不支持多线程读写,相比Memcached会慢。
  • Tair

    • Tair 简介
      1. Tair是由淘宝网自主开发的Key/Value结构数据存储系统,在淘宝网有着大规模的应用。您在登录淘宝、查看商品详情页面或者在淘江湖和好友“捣浆糊”的时候,都在直接或间接地和Tair交互。
      2. Tair是一个Key/Value结构数据的解决方案,它默认支持基于内存和文件的两种存储方式,分别和我们通常所说的缓存和持久化存储对应。
      3. Tair除了普通Key/Value系统提供的功能,比如get、put、delete以及批量接口外,还有一些附加的实用功能,使得其有更广的适用场景。
    • Tair 优缺点
      • 优点:高性能读写、支持三种存储引擎(ddb、rdb、ldb)、支持高可用、支持分布式分片集群、支撑了几乎所有淘宝业务的缓存。
      • 缺点:单机情况下,读写性能较其他两种产品较慢。
  • 测试

img
img
img
img

  • 测试结果

    • Memcached:多核的缓存服务,更加适合于多用户并发访问次数(访问次数较少的应用场景)。
    • Redis:单核缓存服务,在单节点情况下,更加适合少量用户,多次访问的应用场景。
    • redis一般在企业中,是单机多实例架构

企业级缓存中间件Redis

redis简介

  • Redis是一款开源的,ANSI C语言编写的,高级键值(key-value)缓存和支持永久存储NoSQL数据库产品。
  • Redis采用内存(In-Memory)数据集(DataSet) 。
  • 支持多种数据类型。
  • 运行于大多数POSIX系统,如Linux、*BSD、OS X等。
  • redis就是非关系型数据库的一种,存储方式是:key:value
  • 作者: Salvatore Sanfilippo

redis的作用

  1. 会话保持(键过期)
  2. 缓存(放在数据库前面,memcache,mongodb)
  3. 消息队列(kafka)

为什么要用Redis

  1. redis功能全面
  2. redis企业使用率高

redis优点

  1. 高速读写
    • 将所有数据存储在内存,单线程服务,使用C语言
  2. 部署简单,使用稳定
  3. 数据类型丰富
    • String: 字符串类型
    • Hash: 哈希类型
    • List: 列表类型
    • Set: 集合类型
    • Sorted set: 顺序集合类型
  4. 支持持久化
    • 将内存的数据写入磁盘
  5. 多种内存分配及回收策略
  6. 支持事物、锁
  7. 消息队列、消息订阅
  8. 支持高可用
    • 哨兵模式
    • redis cluster
  9. 支持分布式分片集群
  10. 支持的客户端语言很多
    • java
    • php
    • python
    • nodejs
    • C语言

redis帮助

image-20230524164013587

image-20230524164021059

image-20230524164024094

软件特性

  1. 透明性
    • 分布式系统对用户来说是透明的,一个分布式系统在用户面前的表现就像一个传统的单处理机分时系统,可让用户不必了解内部结构就可以使用。
  2. 扩展性
    • 分布式系统的最大特点就是可扩展性,他可以根据需求的增加而扩展,可以通过横向扩展使集群的整体性能得到线性提升,也可以通过纵向扩展单台服务器的性能使服务器集群的性能得到提升。
  3. 可靠性
    • 分布式系统不允许单点失效的问题存在,它的基本思想是:如果一台服务器坏了,其他服务器接替它的工作,具有持续服务的特性。
  4. 高性能
    • 高性能是人们设计分布式系统的一个初衷,如果建立了一个透明,灵活,可靠的分布式系统,但他运行起来像蜗牛一样慢,那这个系统就是失败的。

Redis介绍相关知识

  • 默认端口号6379的由来

    • 6379在是手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字。
    • “MERZ”长期以来被Redis作者antirez及其朋友当作愚蠢的代名词。后来Redis作者在开发Redis时就选用了这个端口。
      1. Alessia Merz 是一位意大利舞女、女演员。 Redis 作者 Antirez 早年看电视节目,觉得 Merz 在节目中的一些话愚蠢可笑,Antirez 喜欢造“梗”用于平时和朋友们交流,于是造了一个词 “MERZ”,形容愚蠢,与 “stupid” 含义相同。
      2. 后来 Antirez 重新定义了 “MERZ” ,形容”具有很高的技术价值,包含技艺、耐心和劳动,但仍然保持简单本质“。
      3. 到了给 Redis 选择一个数字作为默认端口号时,Antirez 没有多想,把 “MERZ” 在手机键盘上对应的数字 6379 拿来用了。
  • Redis库基本介绍

    1. 默认16个数据库,类似数组下标从0开始,初始默认使用0号库
    2. 使用命令 select 来切换数据库。如: select 8
    3. 统一密码管理,所有库同样密码。
    4. dbsize 查看当前数据库的key的数量
    5. flushdb 清空当前库
    6. flushall 通杀全部库
  • 其他介绍

    1. Redis是单线程+多路IO复用技术
    2. 多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)
    3. 串行 vs 多线程+锁(memcached) vs 单线程+多路IO复用(Redis)
    4. 与Memcache三点不同: 支持多数据类型,支持持久化,单线程+多路IO复用

img

Redis的常用功能

  1. 高速读写:
    • Redis在运行时,将数据放在内存当中,利用内存的高性能的特性提高自己的服务性能。
  2. 数据类型丰富:
    • Redis具有丰富的数据类型,可以适用于各种场景。
  3. 支持持久化:
    • 因为Redis的数据是放在内存当中的,当Redis关机或者内存失效时,数据随即丢失,不可找回,为了避免Redis重启时发生类似于雪崩事件,所以Redis官方增加了一个数据持久化的功能。
  4. 多种内存分配及回收策略:
    • Redis可以通过 maxmemory 参数来限制最大可用内存,主要为了避免Redis内存超过操作系统内存,从而导致服务器响应变慢甚至死机的情况。
    • 回收策略主要是删除过期的key以及内存达到 maxmemory 后的淘汰机制。
  5. 支持事务:
    • Redis也支持类似于MySQL数据库那样的事务。
  6. 消息队列、消息订阅:
    • Redis的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易的实现一个高性能的优先队列。
    • 同时在更高层面上,Redis还支持”发布/订阅”的消息模式,可以基于此构建一个聊天系统。
  7. 支持高可用:
    • Redis支持两种高可用集群方式。
    • 哨兵模式
    • redis cluster

Redis使用场景

  1. 缓存
    • 放在数据库前面
  2. 会话保持
    • 登录cookie、session
    • 折扣券,代金券
  3. 排行榜
  4. 计数器
    • 论坛帖子点赞点踩
  5. 社交软件
    • QQ共同好友,微博共同爱好
  6. 消息队列
    • 结合ELK做日志收集

Redis搭建(多实例)

官网地址

Redis官方网站 Redis中文官方网站
http://redis.io http://redis.cn/

image-20230523155229520

搭建步骤

  • 安装步骤

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 下载代码
    wget https://download.redis.io/redis-stable.tar.gz

    # 解压
    tar xf redis-stable.tar.gz

    # 进入目录
    cd redis-stable/

    # 编译
    make

    # 安装
    make install

    # 查看版本
    redis-server --version
    Redis server v=7.0.11 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64
    build=84dacdcf2c79f93f
  • 启动步骤

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 启动服务
    redis-server &

    # 检查端口
    netstat -lntup | grep 6379

    # 连接redis
    redis-cli

    # 退出连接
    127.0.0.1:6379> quit
    127.0.0.1:6379> exit

    # 关闭redis
    127.0.0.1:6379> shutdown
    redis-cli shutdown

    # redis启动读取配置文件
    redis-server /root/redis-stable/redis.conf &

    # 改端口之后如何连接
    redis-cli -p 6380
  • 配置文件修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 编辑配置文件
    vim /root/redis-stable/redis.conf

    # 守护进程模式(后台启动)
    daemonize yes

    # 启动redis不用加&也可以启动
    redis-server /root/redis-stable/redis.conf

    # 指定可连接的主机(监听地址)
    bind 10.0.0.51 172.16.1.51 127.0.0.1

    # 指定pid文件
    pidfile /root/redis-stable/redis.pid

    # 指定日志级别
    loglevel notice

    # 开启redis的日志,并设置日志存放路径
    logfile "/var/log/redis/redis.log"
  • redis的基本操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    # 切换数据库的操作
    select number(0~15)

    # key-value(创建数据)
    set name xxx

    # 查看所有的数据(比较危险,慎用)
    keys *

    # 查看单个数据(有数据)
    127.0.0.1:6379> KEYS name
    1) "name"

    # 查看单个数据(无数据)
    127.0.0.1:6379> KEYS xxx
    (empty array)

    # 查看值
    127.0.0.1:6379[15]> get name
    "xxx"

    # 删除所有库的数据
    flushall

    # 删除所在库的数据
    flushdb
  • redis的安全配置

    • bind:指定IP进行监听

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      # 修改配置文件
      vim redis.conf

      # 指定IP进行监听(可连接网段)
      bind 10.0.0.51 172.16.1.51 127.0.0.1

      # 重启redis
      redis-cli shutdown
      redis-server /root/redis-stable/redis.conf

      # 检查端口
      netstat -lntup

      # db02远程连接
      redis-cli -h 10.0.0.51
      10.0.0.51:6379>
      redis-cli -h 172.16.1.51
      172.16.1.51:6379>
      redis-cli -h 127.0.0.1
      127.0.0.1:6379>
    • protected-mode: 禁止protected-mode yes/no(保护模式,是否只允许本地访问)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      # 修改配置文件
      vim redis.conf

      # 关闭protected(保护模式,是否只允许本地访问)
      protected-mode yes -------> no
      ## 开启时:db02只能连接不能操作
      10.0.0.51:6379> KEYS *
      (error) DENIED Redis is running in protected mode because protected mode is
      enabled and no password is set for the default user. In this mode connections
      are only accepted from the loopback interface. If you want to connect from
      external computers to Redis you may adopt one of the following solutions: 1)
      Just disable protected mode sending the command 'CONFIG SET protected-mode no'
      from the loopback interface by connecting to Redis from the same host the server
      is running, however MAKE SURE Redis is not publicly accessible from internet if
      you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively
      you can just disable the protected mode by editing the Redis configuration file,
      and setting the protected mode option to 'no', and then restarting the server.
      3) If you started the server manually just for testing, restart it with the '--
      protected-mode no' option. 4) Setup a an authentication password for the default
      user. NOTE: You only need to do one of the above things in order for the server
      to start accepting connections from the outside.

      # 重启redis
      redis-cli shutdown
      redis-server /root/redis-stable/redis.conf

      # 再次验证远程连接,就可以操作远端的redis
      redis-cli -h 10.0.0.51
      10.0.0.51:6379> KEYS *
      1) "name"
    • requirepass: 增加连接密码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      # 修改配置文件
      vim redis.conf

      # 设置连接密码
      requirepass 123
      ## 不输入密码时:操作受限
      redis-cli -h 10.0.0.51
      10.0.0.51:6379> KEYS *
      (error) NOAUTH Authentication required.
      10.0.0.51:6379> SELECT 15
      (error) NOAUTH Authentication required.

      # 重启redis
      redis-cli shutdown
      redis-server /root/redis-stable/redis.conf

      # 输入密码远程连接,就可以操作远端的redis
      redis-cli -h 10.0.0.51 -a 123
      10.0.0.51:6379> KEYS *
      1) "name"
  • 开启redis的日志

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 修改配置文件
    vim redis.conf

    # 开启redis的日志,并设置日志存放路径
    logfile "/var/log/redis/redis.log"

    # 创建日志存放目录
    mkdir /var/log/redis

    # 启动服务
    redis-server /root/redis-stable/redis.conf
  • redis库内查看redis配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 查看所有的配置
    CONFIG GET *

    # 查看指定配置
    127.0.0.1:6379> CONFIG GET bind
    1) "bind"
    2) "10.0.0.51 172.16.1.51 127.0.0.1"

    # 临时修改redis配置
    127.0.0.1:6379> CONFIG SET protected-mode yes

redis的多实例

  • 准备多实例环境

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 创建多实例目录
    mkdir -p /data/6380/data
    mkdir -p /data/6381/data
    mkdir -p /data/6382/data

    # 查看多实例目录
    ll /data/
    drwxr-xr-x 3 root root 18 May 23 11:41 6380
    drwxr-xr-x 3 root root 18 May 23 11:41 6381
    drwxr-xr-x 3 root root 18 May 23 11:41 6382
  • 编辑配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 编辑各个实例的配置文件
    vim 6380/data/redis.conf
    port 6380
    bind 127.0.0.1 172.16.1.51 10.0.0.51
    logfile /data/6380/data/redis.log
    protected-mode no
    daemonize yes

    vim 6381/data/redis.conf
    port 6381
    bind 127.0.0.1 172.16.1.51 10.0.0.51
    logfile /data/6381/data/redis.log
    protected-mode no
    daemonize yes

    vim 6382/data/redis.conf
    port 6382
    bind 127.0.0.1 172.16.1.51 10.0.0.51
    logfile /data/6382/data/redis.log
    protected-mode no
    daemonize yes
  • 运行多实例redis

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 启动多实例服务
    redis-server /data/6380/data/redis.conf
    redis-server /data/6381/data/redis.conf
    redis-server /data/6382/data/redis.conf

    # 连接多实例redis
    redis-cli -p 6380
    127.0.0.1:6380>
    redis-cli -p 6381
    127.0.0.1:6381>
    redis-cli -p 6382
    127.0.0.1:6382>

    # 停止服务
    redis-cli -p 6382 shutdown
    redis-cli -p 6381 shutdown
    redis-cli -p 6380 shutdown