2021-05-31redis笔记

https://redis.io/
Redos is an open source (BSD licensed),
Redis是一个开源的源码,BSD协议

百度百科BSD协议:https://baike.baidu.com/item/BSD%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE/2961212?fr=aladdin
BSD开源协议是一个给予使用者很大自由的协议。
基本上使用者可以“为所欲为”,
可以自由的使用,修改源代码,
也可以将修改后的代码作为开源或者专有软件再发布。
但“为所欲为”的前提是你发布使用了BSD协议的代码,
或者以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件:

  1. 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
  2. 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
  3. 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。
    协议介绍
    BSD开源协议(original BSD license、FreeBSD license、Original BSDlicense)
    是一个给予使用者很大自由的协议,BSD代码鼓励代码共享,
    但需要尊重代码作者的著作权。
    BSD由于允许使用者修改和重新发布代码,
    也允许使用或在BSD代码上开发商业软件发布和销售,
    因此是对商业继承很友好的协议。
    而很多的公司企业在选用开源产品的时候都首选BSD协议,
    因为可以完全控制这些第三方的代码,在必要的时候可以修改或者二次开发。

in-memory data structure store,
基于内存数据结构存储,
used as a database,cache,and message broker.
将其作为一个数据库,缓存,以及消息代理。

message broker 消息代理

Redis provides data structures such as strings,hashes,lists, sets,sorted sets with range queries ,bitmaps, hyperloglogs,geospatial indexes,and streams.
redis提供数据结构例如strings字符串、hashes哈希、lists列表、sets集合、sorted sets有序集合和范围查询,bitmaps位图,hyperloglog,geospatial indexes地理空间索引和streams 流。

Redis has built-in replication,Lua scripting,LRU eviction,transactions,and different levels of on-disk persistence,and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.
built-in 内置
redis有内置 replication复制、Lua scripting Lua脚本、LRU eviction(数据淘汰驱逐机制)、Transactions事务,以及不同级别的磁盘持久性,
以及害提供了高性能的via Redis Sentinel哨兵
sentinel 哨兵
via 通过
以及redis集群自动分区

以上就是redis的简介
知道了redis是开源的,有BSD的开源协议。
然后这是一个基于内存 数据结构存储。
可以将它作为一个数据库、缓存、消息代理来使用。
redis提供了一些数据结构例如字符串、哈希、列表、集合、有序集合
以及范围查询、位图、hyperloglog、LRU 全称是 last rencently used
最近使用的数据驱逐算法、
事务、不同级别的磁盘持久化以及提供了高性能的Redis哨兵
via 通过
automatic自动的
partitioning 分割法、分区技术、分隔、细分、分块、分区
redis集群自动分区。

This README is just a fast quick start document.
这个README仅仅是一个快速认识redis的文档。
You can find more detailed documentation at redis.io.
你可以在redis.io上找到更详细的相关文献。

What is Redis?
什么是redis?

Redis is often referred as a data structures server.
redis通常被作为数据结构服务而提及的。
referred 谈及、提到、提及 称…(为);指,涉及,描述 refer的过去分词和过去式

What this means is that Redis provides access to mutable
data structures via a set of commands,
这意味着Redis提供了可变的数据结构通过一套命令。

mutable 易变的,性情不定的,可变的,会变的
a set of 一套,一伙

which are sent using a server-client model
with TCP sockets and a simple protocol.
使用一个服务端-客户端模型通过TCP sockets和一个简单的协议来进行发送
sockets套接字

So different processes can query and modify the same data structures in a shared way
所以不同的进程可以查询和修改相同的数据结构通过一个分享的方式。

Data structures implemented into Redis have a few special properties:
实现到Redis的数据结构具有以下几个特殊属性:

Redis cares to store them on disk
redis关注它们在磁盘上的存储,

even if they are always served and modified into the server momory.
served (给某人)提供;端上;够…吃(或用);接待;服务
serve 的过去分词和过去式

  • [new branch] 6.0 -> origin/6.0

This README is just a fast quick start document. You can find more detailed documentation at redis.io.

这个README只是一个快速快速启动文档。您可以在redis.io上找到更详细的文档。

该READMEwenjain仅仅是一个快速开启的文档(快速认识redis的文档)。

你可以在redis.io该网址上寻找到更详细的相关文献。

What is Redis? (Redis是什么?)

Redis is often referred as a data structures server.

Redis通常被称为“数据结构”服务器。

Redis 通常被作为数据结构服务而被提及到。

What this means is that Redis provides access to mutable data structures via a set of commands,

这意味着Redis通过一组命令提供对可变数据结构的访问,

这意味着Redis提供了访问易变的数据结构的一套命令。

via 通过

a set of 一组

what this means is that 这意味着

via a set of commands 通过一组命令

provides access to mutable data structures 提供对可变数据结构的访问。

which are sent using a server-client model with TCP sockets and a simple protocol.

它使用带有TCP套接字和一个简单协议的server-client模型发送。

它使用TCP sockets套接字以及一个简单的协议来实现一个服务端-客户端模型的交互

So different processes can query and modify the same data structures in a shared way.

因此,不同的进程可以以共享的方式查询和修改相同的数据结构。

所以不同的进程可以通过分享的方式来进行查询和修改相同的数据结构。

Data structures implemented into Redis have a few special properties:

在Redis中实现的数据结构有一些特殊的属性:

数据结构实现redis一些特殊的属性

Data structures implemented into Redis 在redis中实现的数据结构

into prep. 到……里面;触及,碰撞;朝,向;转向;关于;转变成;造成(某种结果);除;对……很有兴趣

  • Redis cares to store them on disk, even if they are always served and modified into the server memory. This means that Redis is fast, but that is also non-volatile.

    Redis关心将它们存储在磁盘上,即使它们总是被服务和修改到服务器内存中。这意味着Redis是快速的,但也是稳定的。

    redis 关注存储在磁盘上的数据,甚至它们总是 served服务和修改服务器内存中的数据,这意味着redis是非常快的,但是这也导致它的稳定性

    volatile 不稳定的

    non-volatile 稳定性 非易失性的,非挥发性的

    even if 即使

    served 被服务 modified 被修改

    into 到什么里面,即使他们总是被服务和被修改到服务器内存中

    server 服务器,memory内存

  • Implementation of data structures stress on memory efficiency, so data structures inside Redis will likely use less memory compared to the same data structure modeled using an high level programming language.

    数据结构的实现强调内存效率,因此,与使用高级编程语言建模的相同数据结构相比,Redis内部的数据结构可能会使用更少的内存。

    数据结构的实现 stress强调在内存 efficiency效率,所以数据结构 inside内部 redis将像使用少量的内存比较相同的数据结构模型使用 一个高级别程序语言

    compared to the same data structure modeled using an high level programming language

    和使用高级编程语言建模的 相同数据结构 相比

    compare to 和什么相比较

    modeled 模仿;模式化;被消防

    the same data structure modeled 建模的相同数据结构

    data structures inside Redis Redis内部的数据结构

    likely 可能的

    stress 强调

    efficiency 效率

  • Redis offers a number of features that are natural to find in a database, like replication, tunable levels of durability, cluster, high availability.

    Redis提供了很多在数据库中很容易找到的特性,比如复制、可调的持久性级别、集群、高可用性。

    Redis提供一些在一个数据库中自然且用于寻找的特性,像复制,tunable 可调谐级别的持久性durability,集群,高可用

    in a database 在数据库中

    a number of 很多

    features that are natural to find 容易找到的特性

    tunable levels of durability 可调的持久性级别

Another good example is to think of Redis as a more complex version of memcached, where the operations are not just SETs and GETs, but operations to work with complex data types like Lists, Sets, ordered data structures, and so forth.

另一个很好的例子是把Redis看作memcached的一个更复杂的版本,其中的操作不仅仅是set和get,而是处理复杂数据类型(如列表、集合、有序数据结构等)的操作。

另一个好的例子是认为redis是作为memcached的一个比较complex复杂的版本,操作上不仅仅只是sets和gets,除了操作使用复杂的数据类型去工作,例如lists列表,sets集合,ordered data structures顺序数据结构,等等

forth 向前

but而是,表转折

operations处理

and so forth 等等

If you want to know more, this is a list of selected starting points:

如果您想了解更多,这是一个所选起点的列表

如果你想要知道更多,以下是一些可选择开始的要点

a list of清单

  • Introduction to Redis data types. http://redis.io/topics/data-types-intro
    • 介绍redis数据类型
  • Try Redis directly inside your browser. http://try.redis.io
    • 直接在浏览器中尝试redis
    • 尝试redis直接在你的浏览器中运行
  • The full list of Redis commands. http://redis.io/commands
    • redis的全部命令清单
  • There is much more inside the Redis official documentation. http://redis.io/documentation
    • 在Redis的官方文档中有更多的内容。
    • 这当中有更多的redis官方文档

Building Redis(构建redis)

Redis can be compiled and used on Linux, OSX, OpenBSD, NetBSD, FreeBSD.

Redis可以编译和使用在Linux, OSX, OpenBSD, NetBSD, FreeBSD

redis可以在linux、OSX、openbsd、netbsd、freebsd中被编译以及使用

We support big endian and little endian architectures, and both 32 bit
and 64 bit systems.

我们支持大端和小端体系结构,以及32位和64位系统。

我们支持大的 endian 字节存储次序 字节序的以及小的字节序的 architectures建筑 架构,包括32位和64位系统。

big endian 大端

little endian 小端

architectures体系结构

It may compile on Solaris derived systems (for instance SmartOS) but our
support for this platform is best effort and Redis is not guaranteed to
work as well as in Linux, OSX, and *BSD there.

它可以在Solaris派生的系统上编译(例如SmartOS),但我们对这个平台的支持是最好的努力和Redis不能保证像Linux, OSX和*BSD那样工作。

它可以在solaris derived衍生/派生的系统上编译(对于实例smartos),我们除了对于这个平台的支持是最容易的,以及redis是不guaranteed保证在linux、OSX、以及*bsd上也可以运行的非常好

It is as simple as:

这很简单

它和%make 一样简单

% make

To build with TLS support, you’ll need OpenSSL development libraries (e.g.
libssl-dev on Debian/Ubuntu) and run:

为了支持TLS,你需要OpenSSL开发库(比如Debian/Ubuntu上的libssl-dev),然后运行:

为了构建通过tls支持,你将需要openssl 开发库才能运行

% make BUILD_TLS=yes

You can run a 32 bit Redis binary using:

你可以运行32位Redis二进制使用

你可以运行一个32位redis二进制 使用:

% make 32bit

After building Redis, it is a good idea to test it using:

之后构建redis,它是一个好的想法来测试它 使用:

% make test

If TLS is built, running the tests with TLS enabled (you will need tcl-tls
installed):

如果构建了TLS,运行启用TLS的测试(您将需要安装“TLS - TLS”):

如果tls被构建,运行测试将tls开启(你将需要安装tcl-tls)

% ./utils/gen-test-certs.sh
% ./runtest --tls

Fixing build problems with dependencies or cached build options(修复依赖项或缓存构建选项的构建问题)

fixing build 修复构建

problems with dependencies or cached build options 依赖项或缓存构建选项的 构建问题

dependencies依赖项

cached build options缓存构建选项

Redis has some dependencies which are included into the deps directory.
make does not automatically rebuild dependencies even if something in
the source code of dependencies changes.

Redis有一些依赖项包含在’ deps ‘目录中。即使依赖项的源代码发生了变化,’ make '也不会自动重新构建依赖项。

redis有一些依赖项是包括在deps目录当中的

make命令不能自动化重新部署依赖项甚至一些在源码当中的依赖项变化

even if 即使

something in the source ocde of dependencies changes 依赖项的源代码发生了变化

When you update the source code with git pull or when code inside the
dependencies tree is modified in any other way, make sure to use the following
command in order to really clean everything and rebuild from scratch:

当你使用’ git pull '更新源代码时,或者当依赖树中的代码以任何其他方式被修改时,确保使用以下命令来真正清理所有东西并从头开始重建:

当你通过使用git pull命令来更新源代码或者当代码当中的依赖项树被任意方式进行了修改的时候,确保去使用跟随按照顺序认真清理任何事物的命令以及从scratch草稿中重新部署

following下面的 接着的

in order to do 为了做,来

really clean真正清理

everything 所有东西

rebuild from scratch 从头开始重建

make distclean

This will clean: jemalloc, lua, hiredis, linenoise.

这将清理:jemalloc, lua, hiredis, linenoise。

这将清理:jemalloc,lua,hiredis,linenoise

Also if you force certain build options like 32bit target, no C compiler
optimizations (for debugging purposes), and other similar build time options,
those options are cached indefinitely until you issue a make distclean
command.

此外,如果你强制某些构建选项,如32位目标,没有C编译器优化(用于调试目的),以及其他类似的构建时选项,这些选项将被无限期地缓存,直到你发出’ make distclean '命令。

如果你强制肯定构建选项例如32位 目标,没有C编译optimizations最佳化(对于debugging调试以排除故障 purposes目的),以及其他的相似构建时间选项,这些选项是被indefintely不确定的缓存直到你发布一个 make distclean 命令

also 此外

certain必然的,确信

compiler编译器

optimizations优化

for debugging purposes用于调试目的

build time options构建时选项

are cached indefinitely 被无限期地缓存

issue 发出

Fixing problems building 32 bit binaries(修复了构建32位二进制文件)

If after building Redis with a 32 bit target you need to rebuild it
with a 64 bit target, or the other way around, you need to perform a
make distclean in the root directory of the Redis distribution.

如果在构建一个32位目标Redis之后,你需要重新构建一个64位目标,或者反过来,你需要在Redis分发的根目录中执行一个“make distclean”。

如果redis通过一个32位目标构建了之后,你需要去重新构建它成一个64位目标,或者其他的方式,你需要去perform执行一个命令make distclean 在redis分发的root目录中

or the orther way around 或者反过来

root directory 根目录

perform 执行

distribution分发

In case of build errors when trying to build a 32 bit binary of Redis, try
the following steps:

当尝试构建一个32位的Redis二进制文件时,如果出现构建错误,请尝试以下步骤:

在当尝试去构建一个redis的32位二进制但是构建错误的情况下时,尝试下面的步骤

binary 二进制文件

binary of redis redis二进制文件

  • Install the packages libc6-dev-i386 (also try g+±multilib).
    • 安装软件包libc6-dev-i386(也可以尝试g+±multilib)。
    • 安装包libc6-dev-i386 (也尝试安装 g+±multilib).
  • Try using the following command line instead of make 32bit:
    make CFLAGS="-m32 -march=native" LDFLAGS="-m32"
    • 尝试使用下面的命令行代替’ make 32bit ':make CFLAGS="-m32 -march=native" LDFLAGS="-m32"
    • 尝试使用下面的命令行代替make 32bit:
      make CFLAGS="-m32 -march=native" LDFLAGS="-m32"

Allocator(分配算符)

Selecting a non-default memory allocator when building Redis is done by setting
the MALLOC environment variable.

在构建Redis时,通过设置’ MALLOC '环境变量来选择一个非默认的内存分配器。

当通过设置malloc环境变量来构建redis完成时,选择一个没有默认内存分配算符。

Redis is compiled and linked against libc malloc by default, with the exception of jemalloc being the default on Linux
systems.

在默认情况下,Redis编译和链接到libc的malloc,除了jemalloc是Linux系统的默认值。

redis被编译以及linked连接反对 libc malloc 通过默认,使用jemalloc异常 在linux系统上。

This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc.

之所以选择这个默认值,是因为事实证明jemalloc比libc malloc的碎片问题更少。

这默认是被选中的,由于jemalloc proven已经证明来 fewer较少的 fragmentation破碎问题比起libc的malloc

proven事实证明

fewer更少

fragmentation problems碎片问题

To force compiling against libc malloc, use:

要强制编译libc malloc,请使用:

为了强制编译against针对libc malloc 使用

% make MALLOC=libc

To compile against jemalloc on Mac OS X systems, use:

要在Mac OS X系统上编译jemalloc,请使用:

要在mac os x系统上强制编译jemalloc,使用

% make MALLOC=jemalloc

Verbose build(详细的构建)

Redis will build with a user friendly colorized output by default.

Redis默认会创建一个用户友好的彩色输出。

redis将被构建通过一个用户友好的colorized给(黑白影片)着色 output输出通过默认的方式

If you want to see a more verbose output use the following:

如果你想看到更详细的输出,请使用以下命令:

如果你想要看到更详细的输出请使用下面命令

% make V=1

Running Redis(运行redis)

To run Redis with the default configuration just type:

要使用默认配置运行Redis,只需输入:

为了通过默认配置运行redis

just type 只需输入

% cd src
% ./redis-server

If you want to provide your redis.conf, you have to run it using an additional
parameter (the path of the configuration file):

如果你想提供redis.conf,你必须使用一个附加参数(配置文件的路径)来运行它:

如果你想要提供你的redis,conf文件,你必须运行它的时候使用一个可添加选项参数(配置文件路径)

additional 附加的 额外的

have to 不得不,必须

% cd src
% ./redis-server /path/to/redis.conf

It is possible to alter the Redis configuration by passing parameters directly
as options using the command line. Examples:

可以通过命令行直接传递参数作为选项来改变Redis配置。例子:

它是可能去命令redis配置,通过passing 暂时的参数直接作为选项 使用在命令行,例如

using the command line 通过命令行

passing parameters directly 直接传递参数

alter改变

% ./redis-server --port 9999 --replicaof 127.0.0.1 6379
% ./redis-server /etc/redis/6379.conf --loglevel debug

All the options in redis.conf are also supported as options using the command
line, with exactly the same name.

conf中的所有选项都支持作为命令行选项,名称完全相同。

全部的选项都在redis.confwenjain当中是被支持作为参数在命令行使用的,通过使用正确的相同的名称

exactly 正确地

with exactly the same name 名字完全一样

Running Redis with TLS:(通过TLS运行redis)

Please consult the TLS.md file for more information on
how to use Redis with TLS.

请参考TLS.md文件,了解如何使用TLS与Redis的更多信息。

在知道如何通过tls使用redis的基础上,请consult查阅 tls.md文件来获取更多的信息

consult查阅

Playing with Redis(操作redis)

You can use redis-cli to play with Redis. Start a redis-server instance,
then in another terminal try the following:

你可以使用Redis -cli来玩Redis。启动一个redis-server实例,然后在另一个终端中尝试以下操作:

你可以使用 redis-cli 来操作redis。开启一个redis-server的实例,然后在另一个窗口尝试下面的命令:

terminal中端

% cd src
% ./redis-cli
redis> ping
PONG
redis> set foo bar
OK
redis> get foo
"bar"
redis> incr mycounter
(integer) 1
redis> incr mycounter
(integer) 2
redis>

You can find the list of all the available commands at http://redis.io/commands.

您可以在http://redis.io/commands上找到所有可用命令的列表。

你可以在该网址上找到所有有效命令的清单

Installing Redis(安装redis)

In order to install Redis binaries into /usr/local/bin just use:

为了安装Redis二进制文件到/usr/local/bin中,只需使用:

按照顺序安装redis库到/usr/local/bin目录下 只需以下步骤

in order to 为了

% make install

You can use make PREFIX=/some/other/directory install if you wish to use a
different destination.

你可以使用’ make PREFIX=/some/other/directory install '如果你想使用一个不同的目标。

你可以使用make PREFIX=/some/other/directory install命令,如果你希望去使用一个不同的destination目的

Make install will just install binaries in your system, but will not configure
init scripts and configuration files in the appropriate place.

Make install只会在系统中安装二进制文件,而不会进行配置 在适当的位置初始化脚本和配置文件。

make install将在你的系统中安装二进制库,否则将不配置初始化脚本以及在appropriate适当的地方配置文件

This is not needed if you want just to play a bit with Redis, but if you are installing
it the proper way for a production system, we have a script doing this
for Ubuntu and Debian systems:

如果你只是想玩一下Redis,这是不需要的,但如果你正在以正确的方式安装它的生产系统,我们有一个脚本来做这个Ubuntu和Debian系统:

如果你想要仅仅只是使用redis操作一下那就不需要,但是如果你是安装它 the proper way正确方法 对于产品系统,对于Ubuntu和Debian系统我们有一个脚本来实现

the proper way 正确的方式

production system 生产系统 (test、dev、prod即production)

% cd utils
% ./install_server.sh

Note: install_server.sh will not work on Mac OSX; it is built for Linux only.

Note: ’ install_server.sh '将不能在Mac OSX上工作;它是专为Linux构建的。

笔记/注意:install_server.sh文件将在mac osx上工作,它是只为linux环境构建

The script will ask you a few questions and will setup everything you need
to run Redis properly as a background daemon that will start again on
system reboots.

该脚本会问你一些问题,并将设置一切你需要运行Redis作为一个后台守护进程,将重新启动系统重新启动。

这个脚本将询问你一些问题并且将创建所有你需要运行redis可能会使用到的东西 在一个背景后台将开始在系统上再一次重启。

a background daemon后台守护进程

reboots重新启动

properly适当地

You’ll be able to stop and start Redis using the script named
/etc/init.d/redis_<portnumber>, for instance /etc/init.d/redis_6379.

你可以使用名为’ /etc/init '的脚本停止和启动Redis。D /redis_<portnumber> ‘,例如’ /etc/init.d/redis_6379 '。

你将可以停止以及开启redis,使用脚本名称/etc/init.d/redis_<portnumber>,对于实例 /etc/init.d/redis_6379

for instance例如

using the script named xxx 使用名叫做xxx的脚本

be able to 可以

Code contributions(代码贡献)

Note: by contributing code to the Redis project in any form, including sending
a pull request via Github, a code fragment or patch via private email or
public discussion groups, you agree to release your code under the terms
of the BSD license that you can find in the COPYING file included in the Redis
source distribution.

注意:任何形式的复述,项目贡献代码,包括发送一个请求通过Github,拉一块代码片段或通过私人邮件或公共讨论组,你同意释放代码根据BSD许可,你可以找到(复制)1文件包含在复述,源分布。

注释:通过贡献代码到redis工程当中使用任何方式,包括发送一个pull推送请求 通过via github,一个代码fragment碎片或者 patch修补通过私人邮件 或者公共的讨论组,你同意放开你的代码在 你可以在copying文件包括在redis源码文献中找到bsd协议地位下

contributing贡献的,起作用的

in any form以任何形式

code fragment代码片段

fragment碎片

Please see the CONTRIBUTING file in this source distribution for more
information.

请参阅源代码分发版中的contribution文件以获得更多信息。

请看贡献文件在这个源码贡献了解更多信息

contributing贡献的

source distribution源分布

Redis internals(redis内部构造)

If you are reading this README you are likely in front of a Github page
or you just untarred the Redis distribution tar ball.

如果你正在阅读这个README,你可能是在Github页面前面,或者你只是解除了Redis分发的tar ball。

如果你正在读这个README文件,你很可能在一个gitHub页面或者你仅仅untarred未浸沥青的 了解了redis分布原始码

In both the cases you are basically one step away from the source code, so here we explain
the Redis source code layout, what is in each file as a general idea, the
most important functions and structures inside the Redis server and so forth.

在这两种情况下,你基本上是一步远离源代码,所以在这里我们解释了源代码的布局,在每个文件作为一个大致的想法,最重要的功能和结构在Redis服务器等。

in both the cases在两种情况下,你是主要地basically 一个步骤总是从源代码中,所以这里我们解释redis源代码分区,对于每一个文件做一个概括,最重要的函数和结构在在redis 服务等。

We keep all the discussion at a high level without digging into the details
since this document would be huge otherwise and our code base changes
continuously, but a general idea should be a good starting point to
understand more. Moreover most of the code is heavily commented and easy
to follow.

我们将所有的讨论保持在较高的层次上,而不深入细节,因为如果不这样做,文档将会非常庞大,而且我们的代码基础会不断变化,但是一个总体的想法应该是一个很好的起点,以便理解更多。此外,大部分代码都有大量注释,易于理解。

我们保持所有的讨论在一个高级别没有挖掘digging 自从该文档想要巨大的otherwise否则以及我们的代码基本的变化continuously连续不断地,但是一个概括应该是一个好的起点来理解更多。moreover而且 代码是heavily很大程度上的,严重的 commented注释以及易于跟随

a high level 较高的层次上

without digging into the details 不深入细节

since 自…以后,因为

would be 将

since …otherwise 因为否则

continuously 连续不断地

to understand more以理解更多

moreover此外

most of the code大部分代码

heavily commented大量注释

easy to follow 易于理解

Source code layout(源代码的布局)

source code 源代码

layout布局

The Redis root directory just contains this README, the Makefile which
calls the real Makefile inside the src directory and an example
configuration for Redis and Sentinel.

Redis的根目录只包含了这个README,这个Makefile调用了’ src '目录中的真正的Makefile,以及Redis和Sentinel的一个配置示例。

redis根目录仅仅包含这个README文件,makefile调用真正生成文件实际在src目录中以及一个示例配置对于redis和哨兵。

You can find a few shell
scripts that are used in order to execute the Redis, Redis Cluster and
Redis Sentinel unit tests, which are implemented inside the tests
directory.

你可以发现一些shell脚本,为了执行redis所使用的脚本,redis集群和redis哨兵单元测试,它们都实现在tests目录当中

你可以找到一些shell脚本,用于执行Redis, Redis集群和Redis哨兵单元测试,这是在“测试”目录内实现的。

Inside the root are the following important directories:

在根目录中有以下重要的目录:

在根目录当中下面是重要的目录

  • src: contains the Redis implementation, written in C.

    ’ src ':包含Redis实现,用C编写。

    src 包含redis的实现,使用c进行编写

  • tests: contains the unit tests, implemented in Tcl.

    ’ tests ':包含单元测试,用Tcl实现。

    tests 包含单元测试,通过使用tcl实现

  • deps: contains libraries Redis uses. Everything needed to compile Redis is inside this directory; your system just needs to provide libc, a POSIX compatible interface and a C compiler. Notably deps contains a copy of jemalloc, which is the default allocator of Redis under Linux. Note that under deps there are also things which started with the Redis project, but for which the main repository is not antirez/redis.

    ’ deps ‘:包含Redis使用的库。所有需要编译的Redis都在这个目录中;你的系统只需要提供“libc”,一个POSIX兼容的接口和一个C编译器。值得注意的是’ deps ‘包含’ jemalloc ‘的副本,这是在Linux下Redis的默认分配器。注意,在’ deps ‘下也有一些东西开始于Redis项目,但它的主库不是’ antirez/ Redis '。

    deps 包含redis使用的库。所有事情都需要编译,redis是在这个目录当中的;你的系统仅仅需要提供libc,一个POSIXcompatible 兼容的接口以及一个c编译器。notably 尤其是deps目录包含了 a copy of一份jemalloc,它是默认的redis在linux下的allocator分配算符。注意在deps目录下也有一些是开启redis工程的,除了这个还有一些主要的仓库不是 antirez/redis

There are a few more directories but they are not very important for our goals
here.

还有一些目录,但它们对我们的目标不是很重要。

这里有一些少量的目录,但是这些他们并不是非常重要对于我们的目标来说

We’ll focus mostly on src, where the Redis implementation is contained,
exploring what there is inside each file.

我们将主要关注’ src ',其中包含Redis实现,探索在每个文件中有什么。

我们将更多地专注于src目录,在这里包含了redis的实现,探索这个目录当中的每一个文件

The order in which files are exposed is the logical one to follow in order to disclose different layers
of complexity incrementally.

为了循序渐进地揭示不同层次的复杂性,文件公开的顺序是遵循的逻辑顺序。

这个当中的文件是被exposed暴露出来的,这当中的每一个文件都是logical合理的,跟随为了disclose公开不同的complexity复杂的incrementally递增地 layers图层面板

in order to 为了

Note: lately Redis was refactored quite a bit. Function names and file
names have been changed, so you may find that this documentation reflects the
unstable branch more closely. For instance in Redis 3.0 the server.c
and server.h files were named redis.c and redis.h. However the overall
structure is the same. Keep in mind that all the new developments and pull
requests should be performed against the unstable branch.

注意:最近Redis被重构了不少。函数名和文件名已经改变,所以你可能会发现这个文档更紧密地反映了’不稳定’分支。例如在Redis 3.0中,’ server.c ‘和’ server.h ‘文件被命名为’ Redis .c ‘和’ Redis .h '。然而,总体结构是相同的。请记住,所有的新开发和pull请求都应该针对“不稳定”分支执行。

注释:lately最近的redis是被重构 quite很,相当 a bit 一点。funciotn函数名称以及文件名称有已经被改变的,所以你可以发现这个必备资料当中反应出unstable 分支 更紧密地。对于在redis3.0版本中的实例 server.c和server.h文件被命名为redis.c和redis.h。然而overall全部的结构是相同的。keep in mind记住,所有新的开发以及拉取unstable分支上的请求应该被再次执行

note 注意

was refactored被重构

quite a bit相当多

function anmes函数名称

for instance 例如

overall structure总体结构,整体结构

keep in mind请记住

performed against the unstable branch 针对unstable分支执行

server.h

The simplest way to understand how a program works is to understand the
data structures it uses. So we’ll start from the main header file of
Redis, which is server.h.

理解程序如何工作的最简单方法是理解它使用的数据结构。我们将从Redis的主头文件’ server.h '开始。

simplest最简单的方式是理解 一个程序如何工作 是来理解它的数据结构如何使用的。所以我们将从redisd的main主要的头部文件开始,这就是server.h文件

All the server configuration and in general all the shared state is
defined in a global structure called server, of type struct redisServer.
A few important fields in this structure are:

所有服务器配置和所有共享状态都定义在一个名为“server”的全局结构中,类型为“struct redisServer”。在这个结构中有几个重要的领域:

所有的服务配置以及in general 总之,通常,一般而言 所有的分享状态是明确定义在一个总的结构叫做server,它的类型 struct redisServer。 少量的重要字段在这个结构中是

all the server configuration所有服务器配置

all the shared state所有共享状态

golobal structure全局结构

  • server.db is an array of Redis databases, where data is stored.

    ’ server.db '是一个Redis数据库的数组,数据存储在其中。

    server.db是一个redis数据库的数组,被用来数据存储

  • server.commands is the command table.

    ’ server.commands '是命令表。

    server.commands 是命令表

  • server.clients is a linked list of clients connected to the server.

    server.clients是连接到服务器的客户机的链接列表。

    server.clients是一个客户端连接服务端的链表

    clients connected to the server 连接到服务器的客户端

  • server.master is a special client, the master, if the instance is a replica.

    server.master 如果实例是副本,则是一个特殊的客户端,即主端。

    server.master是一个特殊的客户端,the master主机,如果实例是一个replica复制品

There are tons of other fields. Most fields are commented directly inside
the structure definition.

还有很多其他的领域。大多数字段都直接在结构定义中进行注释。

还有 tons of许多的其他字段。大量的字段是被直接注释在结构定义的旁边的

Another important Redis data structure is the one defining a client.

另一个重要的Redis数据结构是定义客户端。

另一个重要的redis数据结构是在一个定义的一个客户端。

In the past it was called redisClient, now just client.

在过去它被称为“redisClient”,现在只是“client”。

in the past在过去,它被叫做是redisClient,现在仅仅是client

The structure has many fields, here we’ll just show the main ones:

这个结构有很多字段,这里我们只展示主要的字段:

该结构有很多的字段,这里我们将仅展示最主要的

struct client {
    int fd;
    sds querybuf;
    int argc;
    robj **argv;
    redisDb *db;
    int flags;
    list *reply;
    char buf[PROTO_REPLY_CHUNK_BYTES];
    ... many other fields ...
}

The client structure defines a connected client:

客户端结构定义了一个连接的客户端:

客户端结构定义了一个连接的客户端

  • The fd field is the client socket file descriptor.

    “fd”字段是客户端套接字文件描述符。

    fd 字段是客户端套接字文件descriptor描述符号

  • argc and argv are populated with the command the client is executing, so that functions implementing a given Redis command can read the arguments.

    argc ‘和’ argv '用客户端正在执行的命令填充,这样函数实现一个给定的Redis命令可以读取参数。

    argc和argv be populated with用…填充 用客户端正在执行的命令填充,so that以便所以 函数实现一个给redis命令可以读取参数

  • querybuf accumulates the requests from the client, which are parsed by the Redis server according to the Redis protocol and executed by calling the implementations of the commands the client is executing.

  • reply and buf are dynamic and static buffers that accumulate the replies the server sends to the client. These buffers are incrementally written to the socket as soon as the file descriptor is writable.

As you can see in the client structure above, arguments in a command
are described as robj structures. The following is the full robj
structure, which defines a Redis object:

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
    int refcount;
    void *ptr;
} robj;

Basically this structure can represent all the basic Redis data types like
strings, lists, sets, sorted sets and so forth. The interesting thing is that
it has a type field, so that it is possible to know what type a given
object has, and a refcount, so that the same object can be referenced
in multiple places without allocating it multiple times. Finally the ptr
field points to the actual representation of the object, which might vary
even for the same type, depending on the encoding used.

Redis objects are used extensively in the Redis internals, however in order
to avoid the overhead of indirect accesses, recently in many places
we just use plain dynamic strings not wrapped inside a Redis object.

server.c

This is the entry point of the Redis server, where the main() function
is defined. The following are the most important steps in order to startup
the Redis server.

  • initServerConfig() setups the default values of the server structure.
  • initServer() allocates the data structures needed to operate, setup the listening socket, and so forth.
  • aeMain() starts the event loop which listens for new connections.

There are two special functions called periodically by the event loop:

  1. serverCron() is called periodically (according to server.hz frequency), and performs tasks that must be performed from time to time, like checking for timedout clients.
  2. beforeSleep() is called every time the event loop fired, Redis served a few requests, and is returning back into the event loop.

Inside server.c you can find code that handles other vital things of the Redis server:

  • call() is used in order to call a given command in the context of a given client.
  • activeExpireCycle() handles eviciton of keys with a time to live set via the EXPIRE command.
  • freeMemoryIfNeeded() is called when a new write command should be performed but Redis is out of memory according to the maxmemory directive.
  • The global variable redisCommandTable defines all the Redis commands, specifying the name of the command, the function implementing the command, the number of arguments required, and other properties of each command.

networking.c

This file defines all the I/O functions with clients, masters and replicas
(which in Redis are just special clients):

  • createClient() allocates and initializes a new client.
  • the addReply*() family of functions are used by commands implementations in order to append data to the client structure, that will be transmitted to the client as a reply for a given command executed.
  • writeToClient() transmits the data pending in the output buffers to the client and is called by the writable event handler sendReplyToClient().
  • readQueryFromClient() is the readable event handler and accumulates data from read from the client into the query buffer.
  • processInputBuffer() is the entry point in order to parse the client query buffer according to the Redis protocol. Once commands are ready to be processed, it calls processCommand() which is defined inside server.c in order to actually execute the command.
  • freeClient() deallocates, disconnects and removes a client.

aof.c and rdb.c

As you can guess from the names these files implement the RDB and AOF
persistence for Redis. Redis uses a persistence model based on the fork()
system call in order to create a thread with the same (shared) memory
content of the main Redis thread. This secondary thread dumps the content
of the memory on disk. This is used by rdb.c to create the snapshots
on disk and by aof.c in order to perform the AOF rewrite when the
append only file gets too big.

The implementation inside aof.c has additional functions in order to
implement an API that allows commands to append new commands into the AOF
file as clients execute them.

The call() function defined inside server.c is responsible to call
the functions that in turn will write the commands into the AOF.

db.c

Certain Redis commands operate on specific data types, others are general.
Examples of generic commands are DEL and EXPIRE. They operate on keys
and not on their values specifically. All those generic commands are
defined inside db.c.

Moreover db.c implements an API in order to perform certain operations
on the Redis dataset without directly accessing the internal data structures.

The most important functions inside db.c which are used in many commands
implementations are the following:

  • lookupKeyRead() and lookupKeyWrite() are used in order to get a pointer to the value associated to a given key, or NULL if the key does not exist.
  • dbAdd() and its higher level counterpart setKey() create a new key in a Redis database.
  • dbDelete() removes a key and its associated value.
  • emptyDb() removes an entire single database or all the databases defined.

The rest of the file implements the generic commands exposed to the client.

object.c

The robj structure defining Redis objects was already described. Inside
object.c there are all the functions that operate with Redis objects at
a basic level, like functions to allocate new objects, handle the reference
counting and so forth. Notable functions inside this file:

  • incrRefcount() and decrRefCount() are used in order to increment or decrement an object reference count. When it drops to 0 the object is finally freed.
  • createObject() allocates a new object. There are also specialized functions to allocate string objects having a specific content, like createStringObjectFromLongLong() and similar functions.

This file also implements the OBJECT command.

replication.c

This is one of the most complex files inside Redis, it is recommended to
approach it only after getting a bit familiar with the rest of the code base.
In this file there is the implementation of both the master and replica role
of Redis.

One of the most important functions inside this file is replicationFeedSlaves() that writes commands to the clients representing replica instances connected
to our master, so that the replicas can get the writes performed by the clients:
this way their data set will remain synchronized with the one in the master.

This file also implements both the SYNC and PSYNC commands that are
used in order to perform the first synchronization between masters and
replicas, or to continue the replication after a disconnection.

Other C files

  • t_hash.c, t_list.c, t_set.c, t_string.c, t_zset.c and t_stream.c contains the implementation of the Redis data types. They implement both an API to access a given data type, and the client commands implementations for these data types.
  • ae.c implements the Redis event loop, it’s a self contained library which is simple to read and understand.
  • sds.c is the Redis string library, check http://github.com/antirez/sds for more information.
  • anet.c is a library to use POSIX networking in a simpler way compared to the raw interface exposed by the kernel.
  • dict.c is an implementation of a non-blocking hash table which rehashes incrementally.
  • scripting.c implements Lua scripting. It is completely self contained from the rest of the Redis implementation and is simple enough to understand if you are familar with the Lua API.
  • cluster.c implements the Redis Cluster. Probably a good read only after being very familiar with the rest of the Redis code base. If you want to read cluster.c make sure to read the Redis Cluster specification.

Anatomy of a Redis command

All the Redis commands are defined in the following way:

void foobarCommand(client *c) {
    printf("%s",c->argv[1]->ptr); /* Do something with the argument. */
    addReply(c,shared.ok); /* Reply something to the client. */
}

The command is then referenced inside server.c in the command table:

{"foobar",foobarCommand,2,"rtF",0,NULL,0,0,0,0,0},

In the above example 2 is the number of arguments the command takes,
while "rtF" are the command flags, as documented in the command table
top comment inside server.c.

After the command operates in some way, it returns a reply to the client,
usually using addReply() or a similar function defined inside networking.c.

There are tons of commands implementations inside the Redis source code
that can serve as examples of actual commands implementations. To write
a few toy commands can be a good exercise to familiarize with the code base.

There are also many other files not described here, but it is useless to
cover everything. We want to just help you with the first steps.
Eventually you’ll find your way inside the Redis code base 😃

Enjoy!

以上证明了一点,想要看源码,我这个层次是远远不能够的。
链接地址:https://www.bilibili.com/video/BV1CJ411m7Gc

黑马程序员Redis入门到精通,Java企业级解决方案必看

目录

  1. 课程安排
  2. redis入门-NoSQL介绍
  3. redis入门-redis简介
  4. redis入门-redis下载安装与服务启动
  5. redis入门-redis基础操作
  6. 数据类型-数据类型简介
  7. 数据类型-string基本操作
  8. 数据类型-单指令操作与多指令操作的选择之惑
  9. 数据类型-数值增减操作
  10. 数据类型-数据时效性设置
  11. key的命名规范
  12. 数据类型-hash类型介绍与基本操作
  13. 数据类型-hash扩展操作与使用注意事项
  14. 数据类型-hash实现购物车
  15. hash实现抢购
  16. 数据类型-list类型介绍与基本操作
  17. 数据类型-list阻塞数据获取
  18. 数据类型-list扩展操作删除数据
  19. 数据类型-list实现日志消息队列
  20. 数据类型-set类型介绍与基本操作
  21. 数据类型-set操作随机数据
  22. 数据类型-set数据交并差操作
  23. 数据类型-set实现权限校验
  24. 数据类型-set实现网站访问量统计
  25. 数据类型-set实现黑白名单
  26. set类型介绍与基本操作
  27. 数据类型-sorted_set基本操作(2)
  28. 数据类型-sorted_set实现排行榜
  29. set实现时效性任务管理
  30. set带有权重的任务管理
  31. 数据类型-案例:按次结算的服务控制
  32. 数据类型-案例:微信接收消息顺序控制
  33. 通用指令-key基本操作
  34. 通用指令-key时效性控制操作
  35. 通用指令-key查询操作
  36. 通用指令-key其他操作
  37. 通用指令-db基本操作
  38. 通用指令-db其他操作
  39. jedis-jedis简介
  40. jedis-helloworld(jedis版)
  41. jedis-jedis常规操作演示
  42. jedis-业务请求次数控制案例需求分析
  43. jedis-程序结构搭建
  44. jedis-程序代码实现
  45. jedis工具类制作
  46. jedis-可视化客户端安装
  47. linux环境安装redis-基于Linux安装redis
  48. linux环境安装redis-指定端口启动服务
  49. linux环境安装redis-指定配置文件启动服务
  50. linux环境安装redis-配置文件启动目录管理
  51. 持久化-持久化简介
  52. 持久化-save指令
  53. 持久化-RDB相关配置
  54. 持久化-数据恢复过程演示
  55. 持久化-save指令工作原理
  56. 持久化-bgsave指令与工作原理
  57. 持久化-save配置与工作原理
  58. 持久化-RDB三种启动方式对比与优缺点分析
  59. 持久化-AOF简介
  60. 持久化-AOF持久化策略基本操作
  61. 持久化-AOF重写概念与命令执行
  62. 持久化-AOF自动重写配置
  63. 持久化-AOF重写工作原理
  64. 持久化-RDB与AOF方案对比
  65. 持久化-持久化应用场景分析
  66. 事务-redis事务简介
  67. 事务-事务的基本操作(定义,取消,执行)
  68. 事务-事务的工作流程
  69. 事务-事务操作的注意事项
  70. 事务-锁
  71. 事务-分布式锁
  72. 事务-死锁解决方案
  73. 删除策略-过期数据的概念
  74. 删除策略-过期数据的底层存储结构
  75. 删除策略-定时删除与惰性删除
  76. 删除策略-定期删除
  77. 删除策略-逐出策略
  78. 服务器配置-redis.conf配置
  79. 高级数据类型-bitmaps介绍与基本操作
  80. 高级数据类型-bitmaps扩展操作
  81. 高级数据类型-HyperLogLog
  82. 高级数据类型-GEO
  83. 主从复制-主从复制简介
  84. 主从复制-主从复制的作用
  85. 主从复制-主从复制的三个阶段
  86. 主从复制-工作流程(1)建立连接阶段
  87. 主从复制-搭建主从结构
  88. 主从复制-工作流程(2)数据同步阶段(简)
  89. 主从复制-数据同步阶段注意事项
  90. 主从复制-运行id(runid)
  91. 主从复制-复制缓冲区与偏移量
  92. 主从复制-工作流程(2)数据同步与命令传播阶段(全)
  93. 主从复制-心跳机制与命令传播阶段工作流程
  94. 主从复制-常见问题(1)
  95. 主从复制-常见问题(2)
  96. 主从复制-常见问题(3)
  97. 哨兵-哨兵简介
  98. 哨兵-哨兵结构搭建
  99. 哨兵-工作原理(1)
  100. 哨兵-工作原理(2)
  101. 哨兵-工作原理(3)
  102. 集群-集群简介
  103. 集群-集群存储结构设计
  104. 集群-cluster集群搭建
  105. 集群-设置与获取数据
  106. 集群-主从下线与主从切换
  107. 企业级解决方案-缓存预热
  108. 企业级解决方案-缓存雪崩
  109. 企业级解决方案-缓存击穿
  110. 企业级解决方案-缓存穿透
  111. 企业级解决方案-性能指标监控
  112. 企业级解决方案-性能指标监控命令

课程安排

课程计划

  1. redis基础(windows环境)
    • Redis入门
    • 数据类型
    • 通用命令
    • Jedis
  2. redis高级(linux环境)
    • 持久化
    • redis.conf
    • 事务
    • 集群
  3. redis应用(linux环境)
    • 企业级解决方案

在进行该课程学习之前,我们先将整体的课程安排先跟大家做一下介绍。

那么本课程分为如下几个部分:

第一部分是redis基础,在这部分里面我们要对redis做一个简单的了解,明白redis到底是怎么回事儿,然后学习redis当中对应的数据存储格式、数据类型以及一系列的通用指令,最后要了解一下关于java是如何连接redis并操作redis,由于这部分内容相对来说是属于基础内容,为了降低各位朋友学习的难度,我们把它在windows环境上进行讲解。

第二部分内容,我们要讲到redis的高级。这部分内容相对来说比较多,同时也是一些实用性技能包括redis的持久化、事务,以及redis的配置管理,最后要进行集群的一个搭建。

最后一部分内容就是redis应用了。要讲解若干个企业级的方案,由于这部分东西它的实操性实用性会比较强,我们必须用全真环境去做到,所以说这部分我们要在linux环境上来进行讲解。

Redis入门-NoSQL介绍

redis入门,本章节要进行如下内容的学习

目录 Contents

  • redis简介
  • redis的下载与安装
  • redis的基本操作

首先就是关于redis的一个基本介绍,了解了redis下面我们就要去下载安装redis,那么最后就是我们要学习redis的一些最基本的操作,即动手去玩一下redis。

中国被世界黑的最惨的一天

2007年10月30日,北京奥运会门票面向境内公众第二阶段预售正式启动。上午一开始,公众提交申请空前踊跃。上午9时至10时,官方票务网站的浏览量达到了800万次,票务呼叫中心热线从9时至10时的呼入量超过了380万人次。由于瞬间访问数量过大,技术系统应对不畅,造成很多申购者无法及时提交申请,为此北京奥组委票务中心对广大公众未能及时、便捷地实现奥运门票预定表示歉意。

在讲redis之前,我们还是先从一段历史说起。中国软件业发展周期其实并不是特别的长,那么我们在整个发展的过程中,其实有一些不太好看的东西,与软件有关的被呈现过。我们来看一看中国被世界黑的最惨的一天是哪一天呢?2008年奥运会之前的一个时间。那么奥运会的门票大家都知道它实际上是采用网上预售,其实在2008年中国的互联网发展得只能算是一个中低速。这个时候当我们把这样一个国际性的盛会开放到世界上去的时候,那么门票预定系统就会被全世界的人来冲击。干嘛?大家都想来抢票嘛,奥运会在中国开一次也不容易,中国的这些人抢就够了,世界的人一块抢,结果就造成这么一个事件,叫什么呢?我们成功的把我们的网站给搞崩了。为什么?人太多了。这个事情出来以后呢,就有好事者从专业技术角度来分析,怎么分析呢?他做了一下测算,就是从奥运会门票预售期开放的时候,到底有多少人来看这个网站,把它给整崩了。最后得到了一组数据。

不可回避的问题

奥运会门票预售系统开放第一天,上午9点正式开始售票到中午12点,3个小时内,票务网站被浏览次数达到2000万次。

官网票务网站浏览量平均为:2200次/秒以上。

从网上提交的门票申请:200000张/秒以上。

我们先来看首页的浏览量,这里,我们可以看到

http://www.tickets.beijing2008.cn/zh-cn_static_home.html

打开这个页面加载的字节数为170.216KB。

2200次/秒,也即:374475KB/s,约为365.6984375M。

也就是说这个站点每秒钟处理浏览产生的流量就大概是366M。

而从打开首页,一直到确认订票如果不重复操作的话,应该是10步,在这之前产生的流量要更大。

我们可以这样来理解,一秒钟有2200个用户打开首页,这个是并发的用户数,按比较密集的概率来计划,大概有15000-22000个用户在不同的位置打开这一链接,这一比例应该比较高了。

我用22000个/秒用户来计算,如果用性能测试工具来做性能测试,按每台机器1G内存来计算,其他配置君不悔称为瓶颈,如果一个虚拟用户用600K内存,每台机器拿400M内在来运行用户,也需要近40台机器来实现压力。如果脚本比较复杂

注:每台机器跑600用户,这是在性能测试中,我觉得比较高的使用率了。

每个虚拟用户占用的内存数需要的机器数
600K37台
1024K55台

以上只是从完全没有时间间隔的方式来运行迭代的方式来计算的。

浏览次数达到2000万人次,同时还将网页上的信息给你拉出来聊一聊,说一共网页有多大,然后对应的秒处理流量是多少,大概有什么样的,如果说现在不行的话需要多少台机器才能支撑,真是闲的。我们如果说当时真的技术能提升一些,恐怕也不会这样,仅仅是奥运会的网站有这么大的流量吗?不是。相信在听这个课程的每一个人,到了每年总有那么几天,会有一个切肤之痛。什么呢?买火车票回家。也就是我们的春运。

一个神奇的网站
  • 腾讯科技 科技>要闻>互联网>正文
    • 盘点12306:一个总在“崩溃中”的神奇网站
  • 淘宝崩完12306崩 连着4天,每天都有平台崩溃…
    • 3月21日下午,有网友发现铁轮订票系统12306网站出现崩溃,无法查询余票信息。铁路客服中心回应,目前已上报后台部门核查,正在逐步回复中。

春运对应的以前大家排队买票,咱就不聊了,就说12306上来以后。这个网站呢,一般是两种状态,要么是崩溃中,要么是正在走向崩溃的路上。是吧。我们经常的去吐槽它,怎么票买不着啊,刷不找啊,怎么一点就挂住了,这个确实大家都有感触。那你说像这种12306呢,它毕竟全国就这么一个,那是不是那些多的,做得比较多的就比较成熟些会好一些呢?也未必。来看一下淘宝,当年的马爸爸一手经营的淘宝,其实它也崩,只不过有些人呢他可能不是说天天上去时时刻刻都去用它,感触不到这个事,但是我们也多多少少听说过一些淘宝崩的一些事情。那这些呢其实,对应的都是一个访问量比较大,其实不光是淘宝,就连第一次做这个促销的东哥,也就是京东,它也崩了。第一次没经验,都容易崩,这个大家都能理解。

大型翻车现场
  • 京东促销爆服务器 刘强东:再搞一次
    • 11月1日消息,京东商城今日启动24小时分段限时抢购活动,却因服务器不能支持,致使卖家订单多次提交无效。对此,京东商城CEO刘强东表示“很生气”,要求增加三陪服务器,重新组织活动。

在十一月一号,对应的京东对图书做了一次促销,结果导致什么呢?流量过大,然后东哥就说了再来一场,有些事情吧,它不是说你想再来一场就能来一场的,比如说今天搞个618,明天搞个619,后天搞个620,那还什么意义呢?对吧,那么这些东西呢其实都对应了一个东西,什么呢?我们一块来分析一下它里面到底有什么问题。

问题现象
  • 海量用户
  • 高并发

它的问题现象一,用户比较多,海量用户,这个大家都应该能理解吧?第二个就是,光海量用户还不行,它们一块儿来,高并发,所有人一块儿进来,来访问我们的网站,那么这个时候网站就要扛不住了,那这里边的罪魁祸首到底是什么呢?这些只是现象,其实它的核心问题在于关系型数据库,也就是数据访问这一块儿出了问题。

罪魁祸首-----关系型数据库
  • 性能瓶颈:磁盘IO性能低下
  • 扩展瓶颈:数据关系复杂,扩展性差,不便于大规模集群

那数据访问中,哪些地方会影响它呢?

两个点,第一个是性能,我们知道数据库是保存在磁盘上的,而磁盘的IO性能,也就是读写磁盘的这个性能,相对来说是比较低的,你能来听这么课相信你对计算机也有所了解。CPU的数据交换是和谁做?高速缓存cache,那cache的数据交换和谁做?内存,内存的数据交换和谁做?和硬盘,你就想想提供我们基础数据的这些信息在硬盘上存储,一层一层的往上传递。它可不就是性能比较低吗?你说这磁盘技术再提升再提升,它是远远没有达到我们现在的要求。第二个就是关于我们的这个数据库里面的这种数据存储格式,那对数据库有所了解的同学应该知道,数据库其实不光只存储数据,它更多还要来描述我们的数据关系,可能这张表往这一摆,这张表能关联三张,三张又关联八张,八张可能又关联二十多张,二十多张又关联可能就上百张,上千张。而这上千张不是说一个树形的上去,而是网状的,它相互交叉的这种关系,然后在这当中就比较的错综复杂一些,扩展性能也比较差一些,牵一发而动全身。它不太利于我们做集群,所以说这就是它的一个主要原因。那怎么解决呢?我们找着问题了怎么解决,两条路。

解决思路
  • Nosql
    • 降低磁盘IO次数,越低越好 ------ 内存存储
    • 去除数据间关系,越简单越好 ------ 不存储关系,仅存储数据

第一个IO性能差怎么办?降低磁盘IO的次数,越低越好。你说你数据都从磁盘来的,降低它怎么访问数据呢?我不放磁盘不就行了吗?那放哪儿呢?一会儿再说。

第二个我们尽量剪断数据间的关系,越简单越好。最好这个数据往那一摆,和谁都没关系,这样的效果就会大大降低扩展的不变性。

那么这两个问题解决了,o了。能不能解决呢?必须的嘛,不然我们还在这聊啥呢?

第一个磁盘IO性能低,怎么办?内存,我们用内存来存储它。

第二个关系比较复杂怎么办?就搞关系了,就搞数据。也就是说仅存数据,同时用内存存储。这样的一种解决思路,是什么?其实就是下面要说的这个词语,叫做Nosql。

那什么是NoSQL呢?

Nosql

NoSQL:即 Not-Only-SQL(泛指非关系型的数据库),作为关系型数据库的补充。

作用:应对基于海量用户和海量数据前提下的数据处理问题。

特征:

  • 可扩容,可伸缩
  • 大数据量下高性能
  • 灵活的数据类型
  • 高可用

常见NoSQL数据库:

  • Redis
  • Memcache
  • HBase
  • MongoDB

来我们来看一下,NoSQL这个词,注意它是Not Only SQL,Only即仅,只是的含义。那么Not Only,不仅仅是SQL。注意这个词它是一个比较泛的概念。它最终指向的是什么呢?就指向一个东西,叫做我们干事情不能仅仅只用SQL,那用什么?用其他的。而其他的这种与数据有关的存储访问的这些东西,我们泛指NoSQL,所以不要说这么一句话,NoSQL,NoSQL是一款什么样的SQL,不是,它是泛指,那它是干嘛用的呢?注意,它的定位是对关系型数据库做补充,一定要记得是补充、为什么这么说,真正的数据,你要想存你还得搞到硬盘上,你不能给我全部都扔到内存里去,你内存数据从哪儿来,还是从硬盘来,所以说它给自己的定位是补充。

另外一个,NoSQL出现以后,不是说大家什么情况下都用的,还是基于我们刚才分析的那个点,干嘛?一、海量用户,二、高并发。也就是说,大量的用户过来针对大量的数据进行一个集中的大量的访问出现了问题。那有人说,那我少量用户少量数据能不能用呢?没有说不能用,只是说这就有点杀鸡用牛刀了。所以说在这里边一定要定位好NoSQL它到底是干嘛的。它是做补充的。那么对于NoSQL它应该具有什么样的特征呢?

四个东西了解一下就行了。第一个可扩容可伸缩,有人说为什么这么说呢?提到特征这个词,天下间没有绝对的特征,你一米八我一米五,你比我高,把你扔到NBA里,你还叫特征吗,也算,个最低的一个,所以说,特征一定是对比别人的,所以说没有绝对的特征,都是相对的,而且兴许过了三五年这就不叫特征了,这就叫大众点评化了。第一个可扩容可伸缩就是说NoSQL你对应的这个技术必须得保证扩容性伸缩性不能说还像原来一样的那种,数据库,关系型数据库的那种形式。另外一个,大数据量下它必须要有一个高的性能。这也是我们为什么说要有它的原因。第三个,你数据库那边数据的种类那么多,你对应过来你得能兼容,你就想其实你听这点就知道它就是个对比特征,原来数据库如果只有一种数据的话,它这也不说这事儿了。最后一个高可用,那么关于高可用呢?可能对于刚搞这个的同志呢,不太了解。咱们到后面讲到我们的集群的时候,我们会非常充分的来看到这一点。

那么我们知道有这样的特征了,那市面上现在有多少种这样的数据库呢?或者说多少种NoSQL的解决方案呢?诶我们来看一下常用的NoSQL对应的数据库,反正它也存储数据,我们也叫它数据库。像Redis、memcache、HBase、MongoDB这些,其实这些技术啊,在市场上已经存留了很长时间了,并不是说新出了这么一个技术,那么有了对应的这些解决方案了,那么它们以后主要去干什么呢?其实啊,针对着不同的东西它们所对应的功能或者说体现的价值是不一样的,我们来看一下它对应的解决方案。每一个东西在哪出现。

解决方案(电商场景)
  1. 商品基本信息(MySQL…)
    • 名称
    • 价格
    • 厂商
  2. 商品附加信息(MongoDB)
    • 描述
    • 详情
    • 评论
  3. 图片信息(分布式文件系统)
  4. 搜索关键字(ES、Lucene、solr)
  5. 热点信息(Redis、memcache、tair)
    • 高频
    • 波段性

我们就以电商的场景为例,比如说你去淘宝买东西,每个商品它都会有自己的名称,会有自己的价格,生产商、型号,各种各样的信息,我们把这类信息叫做商品的基本信息。这类信息我们通常把它存到哪儿?因为这种信息基本上固定了,唯一一份,放到mysql数据库里就行,现在的电商解决方案中mysql数据库是属于首选,那么除了这些东西还有吗?还有。

比如说你买完这个东西了,发现不太好,骂一句,去哪里骂,评论骂。另外一个同样的商品在你家描述中这样,在另一家一包装出来又变成另一样,很常见吧,换皮的这种商品,这种就属于什么?商品的详情,商品的描述,这种信息你记得一点,它的访问的时候就要求一定的性能了,因为你一看这个商品啊大量的数据再从数据库中导出来再去读,这个效率明显太低了。那这种数据我们一般放在哪里呢?放在一个高速存储的专门用于这种做文档处理的一个地方,通常我们用MongoDB来解决这个问题,当然你说,我就做电商的,我不放这,ok,咱不抬这个杠,每一家的解决方案都有可能不同。

剩下来还有什么?其实你们看到了有很多电商的网站,文字很少,大部分都是长篇的图,一张一张的挨个往下挪,一张图摊开了看有几百米,其实那是好多图拼接在一块儿的,那么图片是这当中的核心信息,如果我现在告诉你,我卖你一个东西,你连图都看不到,你肯定不买啊,那句话怎么说的,有图有真相对吧,所以第三类图片信息,图片信息它有专用的存储位置,一般我们放到分布式的文件系统中,像各个家它其实都有自己专用的存储服务器,有机会的话大家可以了解淘宝啊,等等都有自己专用的,名字也不一样,实现技术也不太一样,有了这三类信息以后,这个商品基本上算是完整了。

第四类是什么?搜商品的时候一个信息,搜索关键字,这种东西它的存储,如果你放在上面这些例如mysql、mongodb、分布式文件系统中,当然有些是不适用的,比如说分布式文件系统放搜索关键字是肯定不行的。搜索关键字这个东西有它专用的一个存储,那么有些人可能了解一些这样的技术比如说ES、Lucene、solr这种技术,它这里面专门用来存储搜索关键字,来提速。

你说说了这么多,我们说的这个NoSQL,包括我们要讲的redis,在哪儿呢?怎么没它啥事儿啊?

第五类,第五类叫做热点信息,热点信息,什么叫热点,高频,具有波动性。啥意思,也就是说热点信息一定是被访问量很高,它不是随便一个信息拿过来说,它是热点信息,不是。这个信息摆在这里可能今天不是热点,明天就是热点,比如说现在,我说这个详情是热点了,我说那个价格是热点了,都有可能,这种信息我们定位高频,访问性都比较高,第二它具有波段性,它不是时时刻刻都是热点的,哪能热这么久,你见过哪个事儿一热能热三五年的,能热三五天就不错了,这一类信息才是我们要关注的,那我想说这是第五类信息吗?

不是,上面看到的四类信息,哪一种都有可能成为热点,换句话说热点信息是包含前面四种的,并不是说单独出来有一类是热点,没有,这类信息才是我们真正NoSQL要解决的问题,比如说放到我们的redis,后面要讲的这个redis库里面去,这样说呢可能还不是太直观,给大家再看一个东西。

比如说我们现在的基础信息应该放在哪儿?mysql数据库中。基础数据都放在mysql数据库中,但是这么多数据库放一块儿做集群也好做分布式也好,你调用的时候是不是还得把它们综合起来,所以说基础信息存到这儿以后,上一层要把它们连通在一起,连通完以后对外提供一个完整的数据服务,也就是说我对外提供的服务,对外提供的数据是一体的,你不知道它里边有多少,这是因为数据量太多了所以分开放。然后提供到哪儿去呢?上一层,那上一层注意还没有到我们的业务级别,它要进行划分,什么划分呢?

首先将一些商品的评价信息这种信息纯文档类的,可以放到mongodb的集群中,也就是说一系列的mongodb的数据存储,

那接下来还有什么,图片放到专用的图片存储的服务器,FastDFS,还有什么?

比如说我们的搜索关键字,放到我们的solr集群中,当然你说放到es中也没有问题,那还有没有呢?

有,如果哪些信息比较热点,进我们的redis,也就是说,当那些热点比较高访问量比较高的时候,这些数据我们放在这里,然后整体这样一个整体形式对外提供数据,也就是说除了有数据库存储基础数据以外,有些数据根据它的特征要放到不同的地方,它们对外提供数据服务。

这才是我们的一个整体的解决方案。

到这里呢我们就已经知道了我们的整个NoSQL这一块儿东西到底在我们编程中处于一个什么样的位置以及我们后面要做的东西它所处的位置,平行位置还有哪些东西,有关这部分内容我们就讲到这里。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFIzSNuY-1622796382056)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210601014520536.png)]

redis入门-redis简介

Redis

概念:redis(REmote DIctionary Server)是用C语言开发的一个开源的高性能键值对(key-value)数据库。

特征:

1. 数据间没有必然的关联关系
  1. 内部采用单线程机制进行工作

  2. 高性能。官方提供测试数据,50个并发执行1 00000 个请求,读的速度是110000次/s,写的速度是81000次/s。

  3. 多数据类型支持

    • 字符串类型 string
    • 列表类型 list
    • 散列类型 hash
    • 集合类型 set
    • 有序集合类型 sorted_set
    1. 持久化支持,可以进行数据灾难恢复

NoSQL呢,咱们已经说了。那我们这门课讲什么呢?就是讲NoSQL的一种具体体现了。通过这个课程名称大概知道了。什么?redis嘛。那什么是redis呢?来看一下。redis,remote dictionary server,remote什么意思,远程,dictionary什么意思,字典。server就是相当于提供服务嘛,对外提供功能,远程字典服务,什么意思呢?其实这里边最核心的是字典这个词,远程服务是什么?就是你调用它,它给你提供功能嘛,提供的是什么功能,字典的功能,啥意思呢,往后看。它是用C语言开发的,忽略掉不重要,一个开源的,好我们能改它能动它能自己调性能,高性能这是它自己立的牌坊,不重要,最后,键值对数据库,这才是核心。也就是说redis是什么?键值对数据库。那什么是键值对呢?对java语言有所了解的人确实都知道里面有一个模型也可以说是一种存储结构,map映射,其实日常中我们见这种东西非常多,比如说你自己有名字吧,你的名字对应你这个人,这就是一个键值对,一个名称对应一个东西,一个名称对应一个人,一个名称对应一瓶饮料,一个名称对应一条路,都是键值对关系,一个名称找到一个对应的事物,那我们的redis就是这样一个键值对的数据库,它告诉我们什么,redis里面存数据就是一个名对应一个数据。它不像你前边接触的mysql那样的数据库,又是库啊又是表啊,又是字段啊,然后再到里边的值。redis一个名对应一个值。是不是看上去比较暴力,这也是它性能高的主要原因。好,了解了redis是什么,下面就要说说它的特征了,其实这些特征呢,主要还是让大家简单的对它有个整体认识。第一,数据间没有必然的关联关系,这不废话吗,我们刚才说了数据库,关系型数据库它的弱势我们分析出来以后说你得解决这个问题,它redis要没这个特征就完犊子了。它redis就啥都不是了,所以说断开数据关系,这是它redis要做到。其实也能想到里边就一个名对应一个值,一个名对应一个值,它没那么复杂的东西。第二个很重要,单线程机制,我们后面有很多要学的东西解释起来最终都要用到单线程机制。什么叫做单线程,说白了这个人干活儿就是一条线往下走,不会手脑并用,它在处理事情 的时候,这个处理完了处理另外一个,另外一个处理完了处理下一个,原子性,操作原子性比较强。那它就能保证很多安全性的东西,比如说性能问题呢?不着急,高性能来了。比如说单机性能问题。官方测试的数据,人家说了,这多少次多少次,它确实这么快,你说它为什么能做到,人要不整出点特点,还出来咋混。redis的性能还是比较高的,但是这个东西不是绝对的,随着你的后面我们讲到集群的时候,这个性能它会有一些飘忽,另外你玩不好,高性能的东西能让你玩成低性能。比如说人家这个东西做的非常报错,你塞了一个大东西,结果出来的时候出不来,时间很长,高性能都让你玩成低性能了。那么这是它的第三个特征。第四个,就要说说它的数据了。这也是我们后面要学习的一个主要内容。它里面支持五种数据存储格式,我们可以把它叫做数据类型。分别是什么呢?字符串类型string、列表类型list、散列类型hash、集合类型set、有序集合类型sorted_set这五个东西我们后面都会要逐个讲解。在这就不一个个挨个儿的说了。最后一个东西呢稍微有一点点小尴尬,什么呢?我们说redis速度快,内存级的嘛,诶,人非得跟你玩儿持久化。干嘛呢,存到硬盘上,你说有必要吗,你一内存级数据库,你再往硬盘存,你还和mysql,咋要一争天下呀?不是这个意思,我们的数据在内存中存了,它必定会有突然断电的情况,万一你正用的一些数据,没了怎么办,所以说很尴尬,于是我们就像,做一些什么?数据灾难的恢复,比如说正用着呢,断电了,怎么办,它能帮你干件事儿,但是注意啊,redis的持久化不是它主推的东西。好了解完redis了,那以后我们能用redis能点干什么呢?

redis的应用
  • 为热点数据加速加速查询(主要场景),如热点商品、热点新闻、热点资讯、推广类等高访问量信息等
  • 任务队列,如秒杀、抢购、购票排队等
  • 即时信息查询,如各位排行榜、各类网站访问统计、公交到站信息、在线人数信息(聊天室、网站)、设备信号等
  • 时效性信息控制,如验证码控制、投票控制等
  • 分布式数据共享,如分布式集群架构中的session分离
  • 消息队列
  • 分布式锁

来看一看它的应用。第一热点数据的处理,咱们前面反复在提这个,注意热点数据不是指哪一种数据叫热点,是这个数据必然成为热点,比如说各种各样的热点资讯呐,热点新闻呐,包括一些推广的一些东西啊等等等等,这些都可以称之为热点数据,我们就用它来加速。还有什么呢?

后面咱们会说到一些它的一个重要特征就是任务队列,消息队列这么个东西啊,比如说秒杀啊,抢购啊,购票排队啊都可以用这种队列的形式进行。

下面还有即时信息的查看,像有一些在线聊天,聊天室的信息,包括现在直播很火,直播信息,或者不知道大家有没有感触过这个啊,就是你打开这个高德或者百度,你说我准备从哪儿去哪儿,做公交车,上面直接可以显示还有三分钟进站,挺准的,为什么,这种数据刷新速度比较快,高德百度都采用它的一些缓存技术来加速这个东西的展示,保证它的实时性,等等一系列,这是即时类的一些信息,包括一些设备信号啊,这都要求即时的,你速度慢了,不成啊。

剩下的还有什么,时效性的信息控制,比如说大家手机上都收到过验证码吧,五分钟内有效,三十分钟内有效,像这种东西,我们都称之为实时性的信息,它的时效性是可以用redis来做控制的,包括后面的分布式的数据共享,这一块儿呢稍微专业一些,我们说分布式集群架构中的session控制这一块儿它可以做。

另外还有两个东西,一个消息队列,一个分布式锁。这两个东西就不再做过多的解释了,在后面的课程中我们会详细的对这部分内容一个一个案例的来摆出来,有关redis是怎么回事儿以及它以后的一个应用场景我们就简单介绍到这里。

redis入门-redis下载安装与服务启动

目录

  • redis简介
  • redis的下载与安装
  • redis的基本操作

前面呢,我们已经了解了redis是个什么东西,那么接下来呢,咱们就要开始来用了,牵扯到redis的下载与安装。来我们一起来看一下。

redis的下载
  • Linux版(适用于企业级开发)

    • redis高级开始使用
    • 以4.0版本为主版本
  • Windows版本(适合零基础学习)

    • redis入门使用
    • 以3.2版本作为主版本
    • 下载地址:https://github.com/MSOpenTech/redis/tags

对于redis的下载呢,我们要说它分成两个版本,一个是linux版的,一个是windows版的。那么对于linux来说呢,它是企业开发的时候用到的一个环境,而windows呢我们说,通常比较适用于初学者来学习这个东西。那么前面这一块儿咱们说过是用windows版来做这个讲解和演示,那么linux呢,咱们从高阶开始使用,windows这个咱们是redis入门的时候使用,那么对于版本上来说呢,linux版本我们基于4.0作为它的主版本来进行讲解,而windows版本呢,因为这个redis的创始人曾经说过,它做这个东西其实压根就没打算给windows用,做出来以后凑活用吧。然后3.2版目前的一个最新的版本。其实有一定的周期了哈。那么下面呢就来下载它。下载地址是https://github.com/MSOpenTech/redis/tags 。

打开这个网址以后呢,下面列出了redis-windows的所有版本,我们可以看到这些版本号,那么我们就下第一个这个版本了,点击Downloads, 然后在这里边呢我们选择这个Redis-x64-3.2.100.zip 这个版本就行。

在这里我已经下载好了,redis的安装特别的简单,它是个绿色版的软件,啥意思呢,解压缩就可以。解压一下,ok打开以后呢,这就是redis安装完以后对应的一个目录,我们看到这个东西做的那是相当的明了,东西非常的少,那么如果说你把这里面的东西给分一下类呢,其实呢还可以再去稍微的规整下。我们拍一下序,按照类型排一下,关于这种.conf的东西,这些都是配置相关的,config,那么我们回头这块儿我们放到linux环境讲解,windows环境配置咱就不说了。其实里面的配置内容都是一样的。

然后再往后面呢,这有几个文档,这就不说了这是它说明性的一些东西。

那么这里面我们主要要看的是.exe文件,这是我们的可执行文件,那么在这里边,看到这有个redis-server.exe这是个什么,这就是它的启动redis的一个可执行文件,它启动完以后啊是相当于是mysql启动了一个服务器一样,就可以给你提供功能了,但是你怎么操作它呢,需要另外一个叫做redis-cli.exe cli即client,这是它的两个可执行文件。那么对于这个可执行文件redis-check-aof.exe 可执行指令它是干嘛用的呢,它就是用来做我们后面所说的做持久化用的,到时候我们再说。还有一个redis-benchmark.exe这个是用来干嘛的,做性能测试的,那么对于这几个文件来说,我们现在用到哪些呢?用到redis-server.exe、redis-cli.exe这两个。

来咱们把它启动起来。怎么做呢,双击运行redis-server.exe,双击完以后呢, 打开了这个界面,上面有一系列的描述信息,这些信息我们不再windows中做过多解释了,里面有两个东西,你要知道一下,在哪里呢,就是Port:6379,这是什么,redis的端口号,也就是说我们redis对外提供的服务它的端口号是6379。那ip地址是多少呢,就我本机了,你说127.0.0.1也行,你说localhost也行。那么下面这个PID要给大家介绍一下,PID:2460,这个PID是指什么,我们每启动一个redis服务,相当于启动了一个什么,就相当于启动了一个redis对应的对象一样,那么一个对象就是一个实例,这个地方我们可以说是这是个实例的id。那么你把这个界面窗口关掉以后,看一下这是2460,再双击打开redis-server.exe,这个PID的取值就会变,这点要注意。你说我要想启动两个redis服务怎么办,它俩的端口是肯定不能冲突的,所以你双击两次是没有用的,它一闪就没了,闪退,那么你需要去到配置文件中去改它的端口号,把6379改成6380、6381等等,然后你就能启动多个了。当然还有很多种方式,后面我们会讲redis的多种启动方式,那么redis-server.exe是一个服务端。那么对于服务端里面呢需要大家暂时了解的东西不多,下面这是redis服务的执行日志,这句话你可以念得懂的,比如说Server started,Redis version 3.2.100 服务启动,redis版本号3.2.100;回头你都操作了以后它会在redis-server的窗口当中打服务端的日志,了解一下就行了。

来我们看第二个,客户端redis-cli.exe双击,这就连接上了,这是 127.0.0.1:6379> 这就是redis的客户端,也就是在这个地方就能够去操作连接服务端,那么我们称这个东西呢是一个命令行式的,那么命令行式的东西,肯定要有命令啊,是吧。啊,关于redis的启动,我们就说到这里。来我们回到资料上来看一下。

安装redis

核心文件:

  • redis-server.exe 服务器启动命令
  • redis-cli.exe 命令行客户端
  • redis.windows.conf redis核心配置文件
  • redis-benchmark.exe 性能测试工具
  • redis-check-aof.exe AOF文件修复工具
  • redis-check-dump.exe RDB文件检查工具(快照持久化文件)
名称类型大小
EventLog.dll应用程序扩展1KB
Redis on Windows Release Notes.docxMicrosoft Word…13KB
Redis on Windows.docxMicrosoft Word…17KB
redis.windows.confCONF文件48KB
redis.windows-service.confCONF文件48KB
redis-benchmark.exe应用程序400KB
redis-benchmark.pdbPDB文件4,268KB
redis-check-aof.exe应用程序251KB
redis-check-aof.pdbPDB文件3,436KB
redis-cli.exe应用程序488KB
redis-cli.pdbPDB文件4,420KB
redis-server.exe应用程序1,628KB
redis-server.pdbPDB文件6,916KB
Windows Service Documentation.docxMicrosoft Word…14KB

对于redis的安装完以后,对应有这么几个文件。然后这边有各种各样的一些介绍,我在这里边就不一个一个的说了。

启动redis

那么下边启动的时候,服务器启动使用redis-server.exe来启动,这是它的启动界面,对应的端口:6379,然后PID:随机生成的。了解下就行了。

而客户端启动直接双击redis-cli.exe,就行了。那么有些人它喜欢不这样启动,它喜欢在这个地方用CMD执行启动也是可以的,我简单操作一下了解一下就行了。

我只启动一个客户端,服务端我已经启动过了。

#windows+R键,输入cmd,回车,在打开的界面中输入如下指令
e:
cd itheima
#因为这个名称实际上还是比较长的,所以打个dir看一下
dir
#名称是redis一大串,cd打一个r然后打一个tab这样子就帮你自动提醒出来了。
cd Redis-x64-3.2.100
#然后在这个地方你还可以去执行它的各种各样的指令
dir
redis-cli
#回车
#可以比较一下双击redis-cli.exe和命令行CMD开启一个redis-cli客户端连接有什么区别,没什么区别,都一样的,最终落下来的界面都是一模一样的。有关Redis的服务启动我们就说到这里

redis入门-redis基础操作

目录

  • redis简介
  • redis的下载与安装
  • redis的基本操作

redis已经下载好也安装好了。服务端客户端我们也都启动起来了,那接下来咱就要操作这个东西。这就是咱们下面这节redis的基本操作。

那么对于redis,刚才大家已经看到了,它的服务端启动起来以后就给我们提供功能了,而它的客户端是一个命令行,有很多人对于命令行的操作可能不是很熟悉,就一行一行的敲指令让大家进行操作,那命令行这种工具,如果我们要敲它,要学哪些命令呢?这是你要思考的问题,记得以后但凡看到命令行,想四个信息就行了。

第一个你命令行提供功能给我,提供哪些功能。也就是具有功能的命令,首先你得知道,它都有哪些功能命令。

第二个当信息打得多了满屏花里胡哨的你都看不清楚了,清屏指令必须知道。不然你操作的话一会儿就疯掉了。

第三类如果你命令熟悉的话还好,命令不熟悉怎么办?你得有一个获取帮助的指令,帮助信息怎么查。

最后命令行不像我们玩windows,一关×就没了,它怎么退出呢?即它的退出指令。所以有些东西不懂退都退不出来。

命令行模式工具使用思考
  • 功能性命令
  • 清除屏幕信息
  • 帮助信息查阅
  • 退出指令

比如说像redis-server.exe双击后打开的服务想要退出就非常特殊。好我们知道了以后就一个一个来吧。

首先我们先看到它的功能性指令。我们的redis干嘛,存放数据的吧,然后再取出来,所以说先介绍两个最基本的数据命令。什么呢?

信息添加
  • 功能:设置key,value数据

  • 命令

    set key value
    
  • 范例

    set name itheima
    

添加信息和获取信息。

那添加信息你思考,它既然是一个key-value的格式,添加信息肯定key和value都少不了,剩下来就是这个命令叫什么名字。注意先说一点,它添加key对value,一对一,对应的命令,设置key的值为什么,所以它的命令叫做set空格key空格value。来看一个范例,set name itheima就行,那放进去用set,取出来呢?猜一下,get。所以说它的查询指令就是get。

信息查询
  • 功能:根据key查询对应的value,如果不存在,返回空(nil)

  • 命令

    get key
    
  • 范例

    get name
    

注意如果这个可以不存在,你拿不到东西了,它会给你返回一个这个东西nil,它会返回一个空,这里面的空叫做nil。那么对应的指令是什么?get。范例咱就不说了,直接打开redis-cli来看。这些命令得注意一下啊,是服务端的还是客户端的,客户端的啊。服务端的不用管他。

# set key value [EX seconds] [PX milliseconds] [NX|XX]
127.0.0.1:6379> 
#这就存进去了
127.0.0.1:6379> set name itheima
OK
#取值呢?
127.0.0.1:6379> get name
"itheima"
#取出一个不存在的东西会是怎么样呢?就刚才咱说的nil啊,get age 没有这个key,那么就会返回nil
127.0.0.1:6379> get age
(nil)
#没有这个age,那么添加上
127.0.0.1:6379> set age 100
OK
127.0.0.1:6379> get age
"100"
#这就可以了,有人很好奇,要是再次set一下呢,比如说set age 147
127.0.0.1:6379> set age 147
OK
#覆盖了之前的取值,set和get就是一个往里面放一个往外取,set往里放的时候不管你里面有没有,反正是我执行完就这样了不管你那么多;那么到这里咱已经看了两个最基本的指令就是放进去取出来set get;现在是不是信息量有点大了,假如有个时候手有点笨,打成了est name dkjf则一回车就有可能出错误。就会告诉你这有一个未知的命令,你打了它不认识。
127.0.0.1:6379> get age
"147"
127.0.0.1:6379>est name dkjf
(error)ERR unknown command 'est'
#清掉信息命令怎么清,注意clear,回车
127.0.0.1:6379> clear
#在不同的平台上清屏命令不一样像dos就是使用cls命令清屏。这个了解一下就行了,你以后在redis-cli.exe窗口clear打习惯就行了。学习这个阶段要用这个指令。那么这就是我们所说的清屏指令clear。
清除屏幕信息
  • 功能:清除屏幕中的信息

  • 命令

    clear
    

清除屏幕信息,那接着说如果这个指令你不熟悉怎么办,就得用它的帮助信息了,帮助英文叫啥,help,就它了。

只不过它分两组,我们一块儿来看一下。比如说这个set命令怎么用的呢,你可以打一个help空格set,那么get怎么用的呢,同样help空格get回车即可。

很简单哦,get 空格 key,这就是它get的指令格式,然后作用是什么呢,获取一个key对应的值。下面有一个since,什么意思?redis的版本发展得很高了,咱们现在使用的是3.2.100这个版本,但是1.0.0这个版本最早的第一版就有这个命令了。下面有一个它叫做group:string,这是什么意思呢?就告诉你这个命令它属于一个群组,这个群组叫做string。你说这个群组当中都有多少东西呢?来看一下。

127.0.0.1:6379> 
127.0.0.1:6379> help get
GET key
summary: Get the value of a key
since:1.0.0
group:string
#你打一个help,什么都不打然后敲一个回车,它这里就会告诉你这样的一个提示信息,提示信息都说些什么呢,说help空格@加一个群组名,你可以去获取一个列表命令,什么列表命令呢,在这个群组当中的所有列表命令。像刚才咱打的就是help空格加上命令名称,这获取的是什么,获取的是这个帮助,对于这个命令的帮助,也就是你想要看单个命令帮助,直接help空格加上命令名称就行了。而help空格tab干嘛呢,它说可以获取一个列表可能帮助的一个提示,可能帮助的一个提示,那一会儿我们就用一下,最后一个quit,退出。一会儿就能看到这个指令。咱试一下吧。
127.0.0.1:6379> help 
redis-cli 3.2.100
To get help about Redis commands type:
	"help @<group>" to get a list of commands in <goup>
	"help <command>" for help on <command>
	"help <tab>" to get a list of possible help topics
	"quit" to exit
	
To set redis-cli perferences:
	":set hints" enable online hints
	":set nohints" disable online hints
	
Set your preferences in ~/.redisclirc
#打tab键先在help命令后面敲一个空格后再打tab键,它会一直的循环下去,注意循环着循环着它就进到命令里面去了,就不用再往后看了。
127.0.0.1:6379> help @generic
127.0.0.1:6379> help @string
127.0.0.1:6379> help @list
127.0.0.1:6379> help @set
127.0.0.1:6379> help @sorted_set
127.0.0.1:6379> help @hash
127.0.0.1:6379> help @pubsub
127.0.0.1:6379> help @transaction
127.0.0.1:6379> help @conneciton
127.0.0.1:6379> help @server
127.0.0.1:6379> help @scripting
127.0.0.1:6379> help @hyperloglog
127.0.0.1:6379> help @cluster
127.0.0.1:6379> help @geo
127.0.0.1:6379> help APPEND
127.0.0.1:6379> help AUTH
127.0.0.1:6379> help BGREWRITEAOF
127.0.0.1:6379> help BGSAVE
127.0.0.1:6379> help BITCOUNT
127.0.0.1:6379> ......

#我们说help,我们就看一下string群组当中的命令,一般不会手打@string,而是直接空格按tab键,tab键按两下就可以按到@string,然后回车,你会看到很多很多的指令,而刚才咱么查询的命令get就在这个群组当中,这个就可以直接看了不用一个一个自己敲了,set命令也在string该群组当中,set对应命令的格式也在这个当中。当然set命令后面还有一些其他的东西,我们后面再做详细讲解。注意当你看一个群组的所有指令的时候,它不告诉你它属于哪一个群组,为什么,因为help @string你在敲命令的时候看的就是这个群组。所以说这里边这一点需要注意。
127.0.0.1:6379> help @string
APPEND key value
summary: Append a value to a key
since: 2.0.0
BITCOUNT key [start end]
summary: Count set bits in a string
since: 2.6.0
#没有group: string 因为help @string看的就是这个群组,所以该信息进行了忽略。
.....
帮助
  • 功能:获取命令帮助文档,获取组中所有命令信息名称

  • 命令

    help 命令名称
    help @组名
    

来看一下,对于一个帮助信息来说,获取到命令以后,第一行就是它的命令格式,第二行为功能描述,第三行是该命令出现的版本号,第四行是该命令所属的群组。这就是它的帮助信息。通常我们敲到命令的时候,一般不会说莫名其妙的去看一个命令用来干嘛,一般是你对这个命令有了一些基本的认识以后,主要进去查看参数,或者看看它有一些什么说明,不会说打一个help 空格 abc,我看看abc命令是啥,没有这么做的。最后一个呢我们就来说说这个退出指令。

GET key #命令格式
summary: Get the value of a key #功能描述
since: 1.0.0 #出现版本
group: string #所属群组
退出客户端命令行模式
  • 功能:退出客户端

  • 命令

    quit
    exit
    <ESC>
    

退出它格式很多。三种,第一个quit接着回车即可。除此之外还有一个exit接着回车也可以,最里面最过分第一个是什么呢?是ESC键也可以退出。这个东西主要是初学者,要提醒大家,什么呢?就windows环境里面就这点很恶心,比如说打了一串命令abc,然后一看命令敲错了,然后esc取消,结果导致客户端没有了。所以esc慎用。另外以后我们大部分都是在linux环境操作也不存在这种问题,所以说在这呢,给大家算是提个醒 。esc太讨厌了。

有人说那我用windows+r输入cmd指令进去到命令行窗口当中去,会不会出现这种事情呢?

e:
cd itheima
cd Redis-x64-3.2.100
redis-cli
127.0.0.1:6379> get name
"itheima"
#此时敲esc
127.0.0.1:6379> 
#它就可以退出到dos窗口下面来。所以说你要是担心这个事情的话,你就可以用这种方式来去启动,帮助你降低一些操作错误从而带来的一些麻烦。好了有关这些指令呢我们就说到这里,那么到这里呢,咱们的redis入门就已经讲完了。
总结
redis入门
  1. Redis简介
  2. redis的下载与安装
  3. Redis的基本操作
    • set/get
    • clear
    • help

最后简单的回顾一下。

首先我们简单介绍了redis,redis它是一个NoSQL的数据库,它里面采用key-value的形式进行存储。然后接下来我们对redis进行一个下载安装,我们现在这个课程是基于windows 3.2.100做的,后面到高级的时候,是基于linux 4.0.0版本来做下载安装。绿色版,很容易安装,关于它的起服务,开客户端就不说了,最后我们看了一下它的基本操作,分别是set/get、clear、help指令。get/set用来取值放值的,clear用于清屏,help获取帮助信息的。最后那个讨厌的esc就不再详述。有关redis的入门我们就讲到这里,redis入门全部结束。

数据类型-数据类型简介

课程安排

课程计划
  1. redis基础(windows环境)
    • redis入门
    • 数据类型
    • 通用指令
    • jedis
  2. redis高级(linux环境)
    • 持久化
    • redis.conf
    • 事务
    • 集群
  3. redis应用(linux环境)
    • 企业级解决方案

redis的入门咱们已经完成了,大家可以按照我们前面所讲的东西去下载一个redis并且把他安装上,然后通过服务端的启动客户端的启动,然后做几个简单的操作。那接下来咱们就要讲一些具体的东西了,也就是说redis的数据类型。

redis数据类型

目录
  • 数据存储类型介绍
  • string
  • hash
  • list
  • set
  • sorted_set
  • 数据类型实践案例

那对于redis的数据类型这一部分我们一共要要讲七个内容。

首先我们先整体的介绍一下redis的数据存储类型都有哪些。然后接下来我们将针对着一些重要的数据类型最常见的五种数据类型进行一个具体的讲解。最后我们会通过两个案例来把前面所学的数据类型呢,来给演练一遍,相当于串一下,复习一下。好进入到我们的第一个内容,数据类型的介绍。

数据存储类型介绍

业务数据的特殊性
作为缓存使用
  1. 原始业务功能设计
    • 秒杀
    • 京东618活动
    • 双11活动
    • 排队购票
  2. 运营平台监控到突发高频访问数据
    • 突发时政要闻,被强势关注围观
  3. 高频、复杂的统计数据
    • 在线人数
    • 投票排行榜

那么对于数据类型来说,redis到底有多少种数据类型,也就是说它到底有多少种数据的存储格式呢?其实前面大家已经看到了,五种。这里想和大家聊什么呢?就是说redis为什么会这么设计。也就是数据类型的前世今生。

假定你现在是redis的制作人,你打算做几种。五种、八种,还是十种?你肯定不会这么想,你一定是发现某种数据它需要存到redis中了,再将这种数据的特征抽出来然后做成一种数据类型。也就是说你用到哪种,加哪种,久而久之,总结出来了,五种。五种够用了。

有人说要是有新需求怎么办,怎么办,还能怎么办,再加啊,再加几种。所以后面我们还会再介绍几种,它并不是只有这五种。言归正传,咱们说说这些数据类型是怎么来的?还是要回来分析我们的业务情况。就是这些业务数据。redis最初定位是作为缓存使用的,那缓存当中放什么呢?这个就很关键了。比如说我们原始业务中一开始设计的时候就说了,这些数据要进缓存,这些数据都有哪些呢?咱们可以看一下,比如说秒杀,这个大家已经非常的常见了,这个业务。秒杀对应的数据,如果在设计的时候它要是不把它放到缓存当中,回头这个速度,高并发过来,几千人几万人抢那几个商品,崩了怎么办。性能低怎么办。所以一开始设计的时候你就要考虑进去,所以说原始业务功能设计的时候,这种数据它就要放到缓存当中去。

那除了这个以外,原始业务功能还会涉及哪些东西呢。京东618,必须的吧?到那天肯定忙里忙后的那么多人都要上去买东西,这典型就是我家的卫生纸,一年一年的永远用不完。京东有618,天猫呢有双十一。这些东西一定会要使用到缓存。12306也是一样。这么卡春节的时候几十万人几百万人抢那一趟车,会死人的。也些车两个半小时到,同样的四个小时到。你说你抢抢哪个?一定会有大量的数据并发的。那么这个时候作为缓存使用,原始业务就规定了这个数据就要进入缓存。这是一类。

那么第二类是什么呢?

我们的运营平台监控到一些数据忽然间它高频次,什么意思呢,比如说出来一新闻,本来这个新闻也就那么一回事儿,结果忽然被关注,不明真相的吃瓜群众天天就搁这儿看这些东西,那我想问,你最初这个新闻出来的时候你认为它会成为热点数据吗?不一定啊,虽然做新闻的人永远想让它成为热点,但是它不一定真的成为热点,天天有多少无聊的垃圾新闻在往上飘。所以说这种东西它一开始它是不被关注到的。它不能预期得到它会成为热点,但是平台监控到了它高频次访问,那这种东西我们就要把它加入到redis缓存当中去。也就是一开始设计的时候你不知道,这是后来出现的,被强势关注的。

还有什么?

高频复杂的数据统计,比如说,直播现在很火,你看直播上面的这个人数,不停的在跳动,那这些数据你把它存在在数据库中,疯了,进进出出进进出出的,所以这种数据它一定是要作为高访问量数据,属于热点数据。再比如说,投票,现在男团女团很火,很多粉丝给男团中的某个idol投票,疯狂的遇见过这种事情,敲门,亲爱的哥哥姐姐帮个忙能不能帮忙给我的idol投个票,你要知道它们投起票来很疯狂的,这个票实时的在刷新,你说他比她多五票,这边赶快就找人给他投票,要不要快速响应?这就属于高频的这种统计数据,同时它的统计也会复杂一些。这是一种,投票排行榜。

附加功能

系统功能优化或升级

  • 单服务器升级集群
  • session管理
  • token管理

还有没有呢,其实还有,除了我们刚才说的那些东西以外,其实还有一些其他的东西,刚才是作为缓存使用的,现在呢,我们还说一些它的一些附加功能。后面我们会了解到。

比如说你的这个系统发生一些小变化,什么变化呢,原来一台机器解决了,现在客户多了从两百万变成两个亿的用户,高并发,大量的人进来,你数据支撑不住了,怎么办,加机器吧,所有的方案全部都要改,这个时候redis就可以出现了,它可以在一些方案级提供一些它的设计方案。也就是原来不用redis我们能干这事儿,现在整个改了,需要redis进来帮我们解决一些问题,包括后面我们说的session的一些管理,包括一些token令牌的这些管理,都属于这些。那基于我们刚才说的这些东西,redis研究完以后说有五种数据是比较常用的,哪五种呢?就是大家看到的这些了。

redis数据类型(5种常用)
  • string
  • hash
  • list
  • set
  • sorted_set

也就是string、hash、list、set、sorted set这五种,那么这五种也是我们下面要逐个一一介绍的一一讲解的。如果你对java比较了解的话,你可以怎么说呢,做一下想象。就是string是java当中的String字符串,java中也有字符串,hash这个类型在java中可以将它想象成hashMap,它们有很多相似之处,在这里边主要说的是list,对的java中有一个linkedList,链表的格式,这是list的一个模型。再至于set与java中的HashSet以及sorted_set与java中的TreeSet类比一下就好,并不是说它就是它。只不过说这五种数据类型与java中的数据类型比较相似而已。思想模型很像。那么关于数据类型呢,我们说到这里我们就主要后面介绍五种关于数据类型的基本知识的一个介绍。咱们就讲到这里。

数据类型-string基本操作

目录

  • 数据存储类型介绍
  • string
  • hash
  • list
  • set
  • sorted_set
  • 数据类型实践案例

好了,数据类型咱们前面已经做了一个简单介绍,一共五种,下面我们就要逐个讲这五种。接下来咱们就要介绍第一个string数据类型的讲解。那么在讲解这块东西之前,我们还是要把数据类型是怎么回事儿给大家说一下。

redis数据存储格式

  • redis自身是一个map,其中所有的数据都是采用key:value的形式存储
  • 数据类型指的是存储的数据的类型,也就是value部分的类型,key部分永远都是字符串

那么对于redis来说里边存储数据,它的格式是一个映射的关系,就是一个map,key对应value,来我们看一下它的结构。在redis存储空间中如果出现了一个数据,比如说itheima,再来一个数据101,它这只是数据,它们前面有一个名称,也就是我们的key对吧,这个名称key是用来访问这个数据使用的。itheima对应的名称即name,101对应的名称即age。一个名称对应一个数据,也就是我们所说的一个key对应一个value。那么在这当中,左边的这些是key,它们永远都是字符串,没有别的选择,全部都是字符串,而右边这些是value,而我们现在说的数据类型,指的是左边还是右边呢?注意数据类型永远指的是右边,也就是在value这一部分,value这一部分数据的存储,它是什么类型的,左边,key永远都是string类型的,不用考虑啊,接下来咱们讲的string说的都是右边,如果是个stirng的话,是怎么回事儿。啊。有些人总是觉得,诶这左边也是string右边也是string,到底说的是哪个,听着永远都是说的右边,和左边没有关系。左边就是个名称,它不存在什么操作,右边的才有操作。这一点首先要搞清楚,那接下来再说string,你就知道我讲的是什么了。

redis存储空间

keyvalue
nameitheima
age101
名称数据
keyvalue
string类型
  • 存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型
  • 存储数据的格式:一个存储空间保存一个数据
  • 存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用

对于string来说呢,它存的是单个数据,也是redis中最简单的最常用的一种数据存储类型,一个空间存储一个数据,那么这里有一个东西需要给大家明确就是,虽然它里边存的是字符串,但是如果里边它的字符串里面的内容全部都是数字的话,它可以当数字用,但是它仍然是一个字符串,不要觉得里面我存了一个100,它就是个数字了,没那一说,它还是一个字符串。

来说一下它的存储结构。

在redis中,一个key1对应右边的这一个string,itheima就是一个字符串。再来一个key2对应一个4006184000,就这么简单。

下面来看一下它的基本操作。

string类型数据的基本操作
  • 添加/修改数据

    set key value
    
  • 获取数据

    get key
    
  • 删除数据

    del key
    

它的基本操作看完以后,会觉得,嗯?好熟悉,咱们前面讲的那个就是刚打开客户端的时候做的那个小的演示,就是用的string,添加修改用set,获取指令用get,删除数据用del,来简单操作一下。

#添加数据
127.0.0.1:6379> set name itcast
OK
#获取数据
127.0.0.1:6379> get name
"itcaset"
127.0.0.1:6379> set name itheima
"itheima"
127.0.0.1:6379> set age 100
OK
#现在进行get age它是有数据的
127.0.0.1:6379> get age
"100"
#但是我一旦执行del age,这个数据就从redis中抹去了。不再有了,删除完以后会给你返回(integer)1代表删除成功。
127.0.0.1:6379> del age
(integer)1
#再次get的时候即返回nil空,这个时候我们的redis内存中就已经没有age这个东西了
127.0.0.1:6379> get age
(nil)
#那如果再次del age呢?注意它返回的就是(integer)0 了,返回(integer)1代表删除成功,返回(integer)0代表删除失败。在redis中操作如果是以成功失败为标识的话,都是(integer)1和(integer)0;这个一定要记清楚,因为和后面有个东西有混淆。很容易混淆在一起。这是对于redis的一个最基本的操作。set/get/del,除了这三个基本操作以外,它还有几个基本操作,我们来看一下。
127.0.0.1:6379> del age
(integer)0
127.0.0.1:6379> 

以下这四个指令感觉熟悉,set、get前面添加了一个m,这个m是指的multiple,是这个单词,multiple的一个简写,什么意思呢,多个。多个什么意思呢,就是说一次性设置多个,一次性获取多个,就这么回事儿。来看着操作一遍。

  • 添加/修改多个数据

    mset key value1 key2 value2...
    
  • 获取多个数据

    mget key1 key2...
    
  • 获取数据字符个数(字符串长度)

    strlen key
    
  • 追加信息到原始信息后部(如果原始信息存在就追加,否则新建)

    append key value
    
127.0.0.1:6379> 
#因为一次性设置多个,我为了方便就打个简单的,一次进来三个数据回车,通过get指令去看这三个数据都可以看到
127.0.0.1:6379> mset a 1 b 2 c 3
OK
127.0.0.1:6379> get a
"1"
127.0.0.1:6379> get b
"2"
127.0.0.1:6379> get c
"3"
#取值也是一样通过mget取值,mget后面跟着的键与键之间注意空格。
127.0.0.1:6379> mget a b c
1) "1"
2) "2"
3) "3"

#那如果设置的一个键key原来就有怎么办呢,比如说
127.0.0.1:6379> mset d 5 b 6
OK
#原来已经存在的键则set/mset将覆盖原来键所对应的值,原来不存在的该键则进行添加;set和mset是一样的。不用考虑这么多。那这个时候又会有人说那你取的时候会是什么样呢?
127.0.0.1:6379> get b
"6"
127.0.0.1:6379> mget a b c
1) "1"
2) "6"
3) "3"
#w不存在,它会取出nil
127.0.0.1:6379> mget a w c
1) "1"
2) (nil)
3) "3"
#这三个键都没有取出都为空
127.0.0.1:6379> mget m n p
1) (nil)
2) (nil)
3) (nil)
#在这里大家首次看到了 1)、2)、3)这样数据的展现格式,取一个数据的时候呢,它是给一个数据或者是(integer)1/(integer)0,取多个数据的时候呢,它就是1)、2)、3)...的格式,取了多少个,对应的用序号括起来标注了。
#看一个字符string value中有多少个字符
127.0.0.1:6379> set age 200
OK
#它给的也是一个(integer)3,意思为age这个键所对应的值当中一共有三个字符。分别是2,0,0。也就是说它给出来的是这key所对应value的字符的长度
127.0.0.1:6379> strlen age  
(integer)3
127.0.0.1:6379> strlen name
(integer)7
127.0.0.1:6379> get name
"itheima"
#最后一个append指令,看到它的名称就能猜想得到,追加,往一个字符串后面追加,在age该key的值value后面再追加一个300,即append age 300回车即可,看清楚它的返回值是什么,是追加完的长度,6个
127.0.0.1:6379> append age 300
(integer)6
#一共六个字符
127.0.0.1:6379> get age
"200300"
#如果追加的键不存在怎么办呢
127.0.0.1:6379> append mn 300
(integer)3
#append追加不存在的键也成功
127.0.0.1:6379> get mn
"300"
#即append追加的这个变量对应的存储一旦存在的时候就进行追加,不存在的时候就新建一个。如果原始信息存在append就追加,如果不存在就新建。到这里就讲了七个基本指令即set、get、strlen、del、mset、mget、append;有关string的七个基本操作我们就讲到这里。

数据类型-单指令操作与多指令操作的选择之惑

string类型数据的基本操作

前面呢咱们已经完成了string类型的一些基本操作学习,其中呢有两个操作,我们在这里里面需要讨论一下,哪两个操作呢,一个set和一个mset,在这里我们就要来说一下,单数据操作与多数据操作,这两种操作我们究竟应该怎么样去选择。换句话说,你什么时候用,用哪一种。因为它们两个干的活基本一样的。

单数据操作与多数据操作的选择之惑
set key value

vs

mset key1 value1 key2 value2 ...

对于set操作和mset操作来说,它们俩的差别在于什么,set一次设置一个值,mset一次设置多个值,那么对于get和mget是一样的。在这里面,我们不能仅从这里面来思考。我们应该想一下一个单个的操作的完整过程是什么样子的,我们来复原一下:

假如说左边是我们的应用服务器,右边是我们的redis,当然它俩可能是在一台计算机上,咱们不考虑这个,就说当一条指令执行的整个过程中是怎么回事儿,分析完我们就知道这两个东西该怎么选择了。假如说一条指令执行,首先指令到达以后发送给redis,redis拿到指令以后,结束完把结果返回给服务器,那在这个过程中注意,有这么几个地方是需要消耗时间的,第一set指令发送过去这一下要消耗时间,也就是发送指令本身是需要消耗时间的,然后到达以后执行指令,又需要消耗时间,那么redis服务再将结果返回到应用服务器,返回回去又消耗时间,那么这三个时间,你得搞清楚。那么我们现在假定不是一条指令了,而是三条指令,是什么样呢?

应用服务器
=================set指令发送需要消耗时间=================>
<=======返回set指令执行的结果给应用服务器需要消耗时间=======
redis服务
(处理执行set指令需要消耗时间)

如果是三条指令,是单指令操作的话,会怎么做?首先,应用服务器发送set指令到redis服务发送就需要发送三次,然后redis服务执行set命令就需要执行三次,最后redis服务执行完set指令之后返回给应用服务器还需要返回三次即

单指令三条指令的执行过程:时间 × 6 + 时间 × 3

多指令3条指令的执行过程:时间+ × 2 + 时间 × 3

注意在这当中添加了一个小小的加号,为什么要这么做呢,我们可以想一下,一次发送十个数据和一次发送一百个数据还是有点差别的,一次性返回一个数据和一次性返回一百个数据也是有差别的,所以在这当中加了一个+号,加号不代表这比前面的那个多,但是会有一些差距,你说会不会多?不好说,要看你set指令当中放的是什么数据,但是同等指令下mset应该是要比set指令要多的,因为mset指令带的数据量要稍微大一点,那么按照这个逻辑来看的话,你们说应该怎么选择呢,我们就要去均衡一下,究竟你发送的这个时长,和你的执行时长之间的关系,假设我现在要操作五十个数据,我们说还是一次性发五十个比较好这样的话效率高一些,你发五十次和发一次相比还是有差别,你执行时间在那儿摆着,但是如果说,我们想象一下,假如说它要是有一亿条数据让你发呢,你一次发送一亿条数据过去吗?也不成。为什么?那数据量太大了,我们这单线程,就阻塞在那儿了,所有东西都等着这条指令执行完,那不得疯啊。所以说这个时候要真是一亿条数据怎么办?切,比如说我们切到一百万条,发一百次,那这一百万条消耗的时长我们再去测算,看看什么样的数据发送量对我们的性能影响最小,这时我们用那一种就好。你说那这样的话就没有单个的生存空间呐,不是没有单个的生存空间了,是对应的你到底要发送多少,你说我这次两个指令就搞定了,并且都是set,那你选择单个和多个其实差别并不是很大,但是你要是说多了以后,mset和mget这样的指令,毕竟效率是高的。所以说在这里面呢给大家分析一下,没有明确的结论说我们什么时候必须要用mset,但是多指令的时候要考虑一点的就是如果一次发送完它消耗的时长,执行完的时长非常大的话,对于我们这种单线程的操作它是不太适用的,所以这时候一定要及时的切割。你说那切成什么样?反正你切成单个就没有意义了。行了有关这一块内容我们就说到这里。

数据类型-数值增减操作

string的基本操作已经讲完了,下面我们要介绍几个扩展操作。我们先来看一个案例场景。

string类型数据的扩展操作

业务场景

大型企业级应用中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键id必须保证统一性,不能重复。Oracle数据库具有sequence设定,可以解决该问题,但是MySQL数据库并不具有类似的机制,那么如何解决?

在企业级开发中随着我们的业务运行过程中数据量会越来越大,一张表能保存的数据量不能让它无限制的往上扩张,一亿条、十亿条、一百亿条,一万亿条这显然是不现实的,因为它会非常影响查询效率,那这个时候我们怎么办,我们就要采取一种方式,把一张大表切分成若干个小表,甚至将一个库当中的表分散到若干个库当中,那这对应的操作就是我们所说的分库分表,在这里面我们不考虑分库的问题,我们仅仅说分表,那么表有了,表当中的id是一个一个连续的自增的,那如果我要把它分到别的表当中,想过一个问题吗?每一个表控制自己的主键自增,会出事儿的,什么事儿?重复。那一旦重复了那就麻烦了。回头主键重复了那还叫主键吗?于是这里面我们就要解决主键重复的问题。在Oracle数据库中是能做到这个的,它有sequence,序列的概念,它能解决这个问题。但是在mysql当中就没有这样的机制了,怎么办呢?redis可以帮我们做。来我们把原来的一张表分成若干张表以后,我们只要保证一点所有的id都不重复就行。那我们就想一点,就说这个id本来是由数据库自己控制的,如果我们现在要找另一方控制,让它来控制不重复不就行了?redis可以做到。怎么做呢?

idnamenum
104321402933
104321402934
104321402935
104321402936
(表名t_order_20200214)
idnamenum
104321402933
104321402937
104321402939
104321402944
(表名t_order_20200214_001)
idnamenum
104321402934
104321402936
104321402940
104321402943
(表名t_order_20200214_002)
idnamenum
104321402935
104321402938
104321402941
104321402942
(表名t_order_20200214_003)

来介绍第一个扩展操作,专门对数值进行操作的。

解决方案
  • 设置数值数据增加指定范围的值

    incr key 
    incrby key increment
    incrbyfloat key increment
    
  • 设置数值数据减少指定范围的值

    decr key
    decrby key decrement
    

    incr全称叫做increment。

    一块儿来操作下看它究竟是来干什么的。

    首先我们先设定一个数值。

    127.0.0.1:6379> 
    

持久化-持久化简介

课程安排

课程计划
  1. redis基础(windows环境)
    1. redis入门
    2. 数据类型
    3. 通用命令
    4. jedis
  2. redis高级(linux环境)
    1. redis安装
    2. 持久化
    3. 事务
    4. 删除策略
    5. redis.conf
    6. 高级数据类型
  3. redis集群(linux环境)
  4. 企业级解决方案

redis的基于linux系统的安装我们已经讲完了。那接下来我们就要进入redis高级中的第一个重要的知识点–持久化来进行讲解。

redis持久化

那么在redis持久化这一部分知识中呢,我们一共要介绍如下内容:

目录
  • 持久化简介
  • RDB
  • AOF
  • RDB与AOF区别
  • 持久化应用场景

首先什么是持久化,然后我们要针对redis中的多种持久化方案进行注意详细的讲解,并对他们的方案之间做一个比对,最终我们要讲解一下持久化的应用场景。来进入到第一个内容。

持久化简介
意外的断电

在讲解持久化之前呢,让大家思考一个问题,你有没有在写文件的时候忽然遇到了意外的断电,比如说你写一篇论文(论文.docx),在写的时候有没有断电过,那么我们经常会遇到正在操作的时候断电或者说软件崩溃的这种情况,但是一旦软件崩溃以后,会有一些特殊的操作,比如说你能看到“ ~$论文.docx”,或者文件长这样,‘"自动恢复"保存论文.asd’,也可能它是长这样,“论文((Autosaved-307683762565258704)).asd”,那么这几个文件是干什么的呢?其实这就是Microsoft对应的word这款软件给我们提供的自动恢复的功能。干嘛,防止我们丢失。

“自动备份”

那么所谓的“自动备份”,“自动恢复”,它是怎么一回事儿呢?

其实就是将内存中的数据与硬盘中的数据做了一个关联,我们平时写文件都是在哪?都是在内存当中的,那么当内存当中的数据过了一段时间以后呢?它把这个数据放到硬盘上,保存起来(数据保存过程),等到你万一东西丢了,这时候怎么办?它把硬盘上的数据再读回硬盘中,把这个数据给你恢复了,用这种形式来保障我的东西不会丢失(数据恢复过程),起到了一个数据保护的作用,那你想一想,对于一个文档都需要这样,那我们的redis需要不需要呢?也需要的。

因为我们redis是处理数据的,数据丢了会很麻烦,那么redis也有自己的持久化,来看一下。

什么是持久化

利用 永久性存储介质 将数据进行保存,在特定的时间将保存的数据记性恢复的工作机制 称为持久化。

什么是持久化,就是利用像硬盘这样的永久性的存储介质保存我们的数据,当你出现问题的时候,你可以去恢复这些数据,恢复到我们的内存中,也就是我们的redis中,然后再去进行使用,这就是所谓的持久化。

为什么要进行持久化

防止数据的意外丢失,确保数据安全性。

那么为什么要持久化呢?数据安全。万一数据丢了怎么办?它是一个保障方案,所以说这种东西对于我们的redis来说是重要的。知道了为什么要持久化了,那持久化的形式有多少种呢?我们来看一下。

持久化过程保存什么
  • 将当前数据状态进行保存,快照形式,存储数据结果,存储格式简单,关注点在数据
  • 将数据的操作过程进行保存,日志形式,存储操作过程,存储格式复杂,关注点在数据的操作过程

首先redis里边也好,其他的东西里边也好,持久化保存的东西就只有一个东西,数据。

那么redis中的数据存储是什么样的,全是二进制。

10011001110000001
00101001011010110
10110011001110000
00100101001011011

以上为数据(快照)

这是它的数据,那我们想,假如说,现在这种数据有了,我把这组数据干嘛?每过一分钟,在你的 计算机上保存一下,每过一分钟在你的计算机上保存一下,这样是不是就不会丢了?

就算丢失,也只会丢失一点,起码不会全部丢失。那么这种保存方案保存的是什么呢?我们称之为快照(数据(快照)),也就是说对这个信息快速拍个照片,然后放到一边,用的时候再用这个快照来进行恢复。这是第一种方式。就是数据当前的形式全部保存起来,放在一块儿,然后回头去恢复它,我不管你数据是怎么来的,我只关注一点现在数据长什么样。那除了这种形式之外,还有没有呢?

我把你的整个数据操作过程记录下来,行不行?

删除第三行
第四行末位添加字符x
删除第二到第四行
复制第三行粘贴到第五行

以上为过程(日志)

大家如果用到一些软件会发现,你写了一点东西结果发现,哟,写错了,我得恢复过去,ctrl+y , ctrl+z 撤销,其实它记忆的就是你的步骤,一步一步的,回头一看没错,你再恢复过来,ctrl+y,ctrl+y的时候,你还能把他恢复成原来的这种格式,那这种记录的是什么,是它的整个操作过程。我们说其实就是像日志一样的这种东西。那么用这种形式我们也可以保存数据,但是它保存的不是直接的数据,而是什么?而是整个操作过程,那么这部分形式的数据也可以用来恢复数据。好了我们介绍了两种持久化的方式,那redis用的是哪一种呢?我告诉你,两种都有,左边的数据(快照)也有,右边的过程(日志)也有。在redis中左边的这种形式叫做RDB,右边的这种形式叫做AOF,那么接下来我们就要对这两种进行一个详细的学习。好了有关持久化的基本介绍我们就讲到这里。

持久化-save指令

目录

  • 持久化简介
  • RDB
  • AOF
  • RDB与AOF区别
  • 持久化应用场景

持久化我们已经了解了是怎么一回事儿了,接下来我们就要讲第一个持久化方案RDB。

在讲这个东西之前呢,我们先来想一下既然你是保存数据,一定是做一件事儿,那么做一件事儿不外乎三个条件

  • 一、谁干的

  • 二、什么时间干的

  • 三、干的什么事情

RDB启动方式

谁、什么时间、干什么事情

那在这里面我们保存数据一定是一个指令,那么做这个指令的时候,这三个东西分别是谁呢?

一、谁干的,我们用户干的,其实你是通过客户端来发一个指令来做这件事儿。

第二、什么时间,你什么时间都可以,你只要执行这个指令它马上就会保存下。

第三、干什么事情,干什么?就是保存数据啊。

那我们只需要知道对应的命令即可。

命令执行:

  • 谁:redis操作者(用户)
  • 什么时间:即使(随时进行)
  • 干什么事情:保存数据

来看一下持久化的命令。

RDB启动方式-save命令
  • 命令

    save
    
  • 作用

    • 手动执行一次保存操作

save命令,每执行一次它就会保存一次数据。来我们一起看一下。

#redis-cli客户端
#先看下有没有数据
127.0.0.1:6379> keys *
(empty list or set)
#没有数据我们往里放一个数据,回车
127.0.0.1:6379> set name 123
OK
#放好了我们下边做一件事情,我们去执行一下save,它倒是很简单什么东西也没有,那么我们到redis目录当中看一看有没有被持久化呢,它持久化的文件在哪儿呢?
127.0.0.1:6379> save
OK
127.0.0.1:6379> 

#redis-server服务端 守护进程启动
#注意前面我们设置过一个东西,还记得吧,它会在data目录中生成数据,我们设定的目录,于是我们进入到data目录。
[root@localhost redis-4.0.0]# cd data
[root@localhost data]# ll
-rw-r--r--. 1 root root 2824 Oct 13 03:28 6379.loc
-rw-r--r--. 1 root root 170 Oct 13 03:28 dump.rdb
# 这里多了一个文件叫dump.rdb,这个rdb就是我们的持久化的文件了。来看一下
[root@localhost data]# cat dump.rdb
#现在打开以后呢,因为rdb文件的内部都是采用二进制来记录的,所以说你并不一定能看得懂,现在这里边已经有数据了,那么我要做的事情是,我把这个文件删掉,我在redis-cli端再次save一下看一看
[root@localhost data]# rm -rf dump*
[root@localhost data]# ll
total 4
-rw-r--r--. 1 root root 2824 Oct 13 03:28 6379.log
#没有dump.rdb文件之后,然后去到redis-cli中输入命令

#redis-cli客户端
#再次执行一遍save命令
127.0.0.1:6379> save
OK
127.0.0.1:6379> 

# 再看到redis-server守护进程启动端
[root@localhost data]# ll
-rw-r--r--. 1 root root 2871 Oct 13 03:30 6379.log
-rw-r--r--. 1 root root 170 Oct 13 03:30 dump.rdb
# 我们会发现是不是又生成dump.rdb文件了, 注意在redis-cli再添加一个东西

#redis-cli客户端
127.0.0.1:6379> set age 39
OK
#然后再次save一下
127.0.0.1:6379> save
OK
127.0.0.1:6379> 

#redis-server守护进程后台启动端
[root@localhost data]# ll
-rw-r--r--. 1 root root 2818 Oct 13 03:30 6379.log
-rw-r--r--. 1 root root 177 Oct 13 03:30 dump.rdb
#再次来比对一下,他们两个文件大小是不是已经发生变化了,这个就是用来执行save命令操作以后保存数据用的那个文件。那么它现在里面长成什么样呢?
[root@localhost data]# cat dump.rdb
# 同样仍然是打不开该文件,尽管我们没办法去用我们的文字去阅读它,但是你可以看到一些东西,该文件可以显示成键 英文名,上一次显示了name,这一次可以看到age以及name,通过这里你也可以观察出,一些区别。回到我们的资料中。


使用RDB这种形式来进行持久化,用到的命令是什么?save。每保存一次它会去生成一个叫做.rdb后缀的文件,用来保存什么?当前的快照信息。有关save指令,我们就讲到这里。

持久化-RDB相关配置

现在呢,我们的文件已经知道,它是怎么加载的了,那么问题来了,这个名称为什么叫做dump.rdb文件名呢,能不能改呢,接下来咱们要学习几个配置。

RDB启动方式-save指令相关配置
  • dbfilename dump.rdb

    说明:设置本地数据库文件名,默认值为dump.rdb

    经验:通常设置为dump-端口号.rdb

  • dir

    说明:设置存储.rdb文件的路径

    经验:通常设置成存储空间较大的目录中,目录名称 data

  • rdbcompression yes

    说明:设置存储至本地数据库时是否压缩数据,默认为yes,采用LZF压缩

    经验:通常默认为开启状态,如果设置为no,可以节省CPU运行时间,但会使存储的文件变大(巨大)

  • rdbchecksum yes

    说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行

    经验:通常默认为开启状态,如果设置为no,可以解决读写性过程约10%时间消耗,但是存储一定的数据损坏风险

第一个dbfilename dump.rdb设定我们存储的数据文件的名称。dbfilename 后面跟上你的名称,通常会设置成我们的端口号,这样的话你好识别一些。

第二个dir,咱么前面已经设了,说了这个地方咱们用的是data,所以dump.rdb文件会出现在data目录下。

第三个是什么呢?rdbcompression yes 用不用压缩格式,如果用压缩格式的话呢,它会小一些。

最后一个呢,rdbchecksum yes 是你加载这个文件的时候要不要去校验一下,万一这个文件损坏了怎么办?那么校验过程呢它会消耗一定的性能,但是对于我们平常开发来说呢,启动的时候我们基本上不用去管它,所以我们把这四个配置给它加上。

那在哪里加上呢?配置文件当中进行修改。

咱们一个一个来进行。来到服务端这边。

[root@localhost redis-4.0.0]# cd data
#进入到data目录当中,去看一下这个dump.rdb文件,
[root@localhost data]# ll
total 12
-rw-r--r--. 1 root root 4348 Oct 13 03:33 6379.log
-rw-r--r--. 1 root root 177 Oct 13 03:30 dump.rdb
#在这里有它的存储文件,dump.rdb,我们下边要去改我们的配置,最终会影响它
[root@localhost data]# cd ..
#退出该当前目录
[root@localhost redis-4.0.0]# cd conf
[root@localhost conf]# ll
#我们去改我们的6379这个配置文件
-rw-r--r--. 1 root root 65 Oct 13 -2:39 redis-6379.conf
-rw-r--r--. 1 root root 65 Oct 13 -2:47 redis-6380.conf
[root@localhost conf]# vim redis-6379.conf
--------------------------------
#下边呢我在该文件当中要加几个参数了
port 6379
daemonize yes
logfile "6379.log"
dir /redis-4.0.0/data
#dir参数已经配置了就不再说了
#给数据文件起什么名字呢,一般叫做dump-,代表这是rdb的存储,dump-端口号.rdb,后面还是.rdb,这些名字不要去乱改
dbfilename dump-6379.rdb
#另外还有两个配置,这两个都是配置成yes
#开启压缩
rdbcompression yes
#开启加载检测
rdbchecksum yes
--------------------------------
#保存文件退出,esc+:+wq退出
#现在这个redis服务的配置文件已经修改了,我们把这个服务给它重新启动一下,先杀它的进程

[root@localhost conf]# cd ..
[root@localhost redis-4.0.0]# ps -ef|grep redis-
root 85923 1 0 03:33 ? 00:00:00 redis-server *:6379
root 85929 83384 0 03:34 pts/3 00:00:00 redis-cli
root 86002 66271 0 03:38 pts/1 00:00:00 grep --color=auto redis-
[root@localhost redis-4.0.0]# kill -s 9 85923
#有没有这种热启动redis的,有,讲到那儿再说,当前用传统的方式原始的方法来做这种恢复
[root@localhost redis-4.0.0]# clear
[root@localhost redis-4.0.0]# redis-server conf/redis-6379.conf
[root@localhost redis-4.0.0]# 

#redis-cli客户端输入指令
#查一下
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set name 123
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379> set age 39

#接着看redis-server守护进程后台启动端
[root@localhost redis-4.0.0]# cd data
#进入到data目录下
[root@localhost data]# ll
-rw-r--r--. 1 root root 5760 Oct 13 03:38 6379.log
-rw-r--r--. 1 root root 170 Oct 13 03:38 dump-6379.rdb
-rw-r--r--. 1 root root 177 Oct 13 03:30 dump.rdb
#现在来看data目录下就已经有了dump-6379.rdb了,dump.rdb是上一次存留的,进行删除
[root@localhost data]# rm -rf dump.rdb
#然后再去看新文件dump-6379.rdb
[root@localhost data]# cat dump-6379.rdb
#我们来看一下现在这里边是不是只有一个name,我们去redis-cli再去set一下即

#redis-cli客户端
127.0.0.1:6379> set age 39
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379> 

#然后再来看redis-server守护进程后台启动端
[root@localhost data]# cat dump-6379.rdb
#该文件当中就又多了一个age了,通过这个东西我们可以去看到刚才咱们dbfilename dummp.rdb这个设置的文件名已经生效了。至于它的这种压缩格式包括它的这种检测都是性能级别的,咱们在这就不再说了。
#有关save指令对应的相关配置我们就讲到这里。



持久化-数据恢复过程演示

当前呢,我们的数据已经保存上去了,那我们如何来看它是不是能恢复呢?这个事情也比较简单,来我们这边先将客户端先退了。

127.0.0.1:6379> 
#ctrl+c退出
[root@localhost redis-4.0.0]# clear
#清屏
[root@localhost redis-4.0.0]# 

#然后在服务端将服务杀掉,先看服务进程,redis-server守护进程后台启动端
[root@localhost data]# ps -ef|grep redis-
root 85129 1 0 02:46 ? 00:00:03 redis-server *:6379
root 85906 66271 0 03:33 pts/1 00:00:00 grep --color=auto redis-
#我们redis服务进程id为85129,杀掉
[root@localhost data]# kill -s 9 85129
#再来看一下他还在不在
[root@localhost data]# ps -ef|grep redis-
root 85906 66271 0 03:33 pts/1 00:00:00 grep --color=auto redis-
#该进程已经没有了,清屏
[root@localhost data]# clear
#现在再去启动一下这个服务,同时我们要去看什么,里边有没有数据。如果有数据就证明它恢复过来了
[root@localhost data]# cd ..
[root@localhost redis-4.0.0]# redis-server conf/redis-6379.conf
#看服务是否真的启动了
[root@localhost redis-4.0.0]# ps -ef|grep redis-
root 85923 1 0 03:33 ? 00:00:03 redis-server *:6379
root 85928 66271 0 03:33 pts/1 00:00:00 grep --color=auto redis-
[root@localhost redis-4.0.0]# 


#redis-cli 用户端去连接启动的redis服务
#因为是6379的所以就不需要打端口号,直接连接即可
[root@localhost redis-4.0.0]# redis-cli 
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> get name
"123"
127.0.0.1:6379> get age
"39"
127.0.0.1:6379> 
#通过这里你也能发现,原来数据是不是真的留下来了,那么在什么时候恢复的数据呢?实际上是在它启动的时候,把数据加载上来的

持久化-save指令工作原理

RDB启动方式-save指令工作原理

save指令我们已经看过了,下面我们要说一下它的工作原理。

假定我这里边有四个客户端,发过来四条指令

客户端1:

127.0.0.1:6379> set key1 value1

客户端2:

127.0.0.1:6379> set key2 value2

客户端3:

127.0.0.1:6379> save

客户端4:

127.0.0.1:6379> get key1

都发给同一个redis服务器,那么这个时候由于它们是不同的客户端,发送有一个先后的顺序,所以我们说假如都是按照这个顺序到达redis服务器的话,那么在redis内部,这四个指令实际上是有一个先后的执行顺序的,因为我们知道redis是单线程的。假定这就是它执行的一个序列,那么四个指令一个一个进去之后呢,按照它的顺序排好,等到执行的时候,第一个执行完,第二个执行,第二个执行完第三个执行,反复的把它们执行完毕。注意这里边有一个问题,加入现在这些指令一个一个的排好对队了,我们在执行save指令的时候如果它现在执行时间很长怎么办?那么在它后面的这些指令就会得等着这个指令执行完,也就是说当我们执行save指令的时候一旦执行时间过长,它就会阻塞整个redis服务器,那么直到整个RDB的过程完了以后,它才可以继续往下执行指令。这里边就要告诉大家一点,线上环境中不建议使用save指令这样的操作来执行。因为它会很拉服务器的性能效率,有可能会造成一个长时间的阻塞,那么这个时候对应的服务器的性能就会还是灾难性,所以了解这个东西以后,你就知道了这种指令在执行的时候它是具有一定的风险性的。那有没有方案能解决呢?有,后面我们会介绍到第二种RDB的工作方式。它就能够较好的解决这个问题。

...... get save set set
get save set
get save
get

以上为:单线程任务执行序列

注意:save指令的执行会阻塞当前redis服务器,直到当前rdb过程完成为止,有可能会造成长时间阻塞,线上环境不建议使用。

持久化-bgsave指令与工作原理

RDB启动方式
数据量过大,单线程执行方式造成效率过低如何处理?

后台执行。

前面我们说了当数据量过大的时候单线程执行的这种形式会造成一个效率的降低,怎么办呢?这就要,我们说第二种解决方案,就能够解决前面这个问题了。怎么玩儿?注意四个字:后台执行。

也就是我不跟大家抢了,那按照前面我们分析的,那三个东西,分别又是什么呢?

一、谁来操作,注意指令还是我们使用者来发起

二、什么时间呢,你指令敲的是当时,但是实际的执行时间,我告诉你,不由你管,后台会用它的方式去进行执行

三、干什么事儿呢?还是保存数据,这个是不变的。来我们看一下它对应的指令叫做什么。

  • 谁:redis操作者(用户)发起指令,redis服务器控制指令执行
  • 什么时间:即时(发起);合理的时间(运行)
  • 干什么事情:保存数据
RDB启动方式-bgsave指令
  • 命令

    bgsave
    
  • 作用

    手动启动 后台保存操作,但不是立即执行

bgsave,bg是什么,background,bgsave,后台save,执行这个指令以后呢,将在后台执行保存操作,但是它不是立即执行的,来我们一起来看一下。

#这是我们前面操作的一个数据结果
[root@localhost redis-4.0.0]# cd data
[root@localhost data]# ll
total 12
-rw-r--r--. 1 root root 5807 Oct 13 03:39 6379.log
-rw-r--r--. 1 root root 5807 Oct 13 03:39 dump-6379.rdb
#这有一个rdb文件,
[root@localhost data]#

#redis-cli 在redis-cli有对应的两个key进行了保存操作
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set name 123
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379> set age 39
OK
127.0.0.1:6379> save
127.0.0.1:6379> 
#下边再加进去一个东西
127.0.0.1:6379> set addr beijing
OK
#下面执行bgsave
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> 
#执行以后,bgsave命令给了一个提示信息,叫做后台保存已经开始,但是它有没有告诉你有没有执行完成呢?没有。
127.0.0.1:6379> 

#在来看redis-server守护进程后台启动端
[root@localhost redis-4.0.0]# cd data
[root@localhost data]# ll
total 12
-rw-r--r--. 1 root root 5807 Oct 13 03:39 6379.log
-rw-r--r--. 1 root root 177 Oct 13 03:39 dump-6379.rdb
#以上这是当前的状态,再次查询
[root@localhost data]# ll
total 12
-rw-r--r--. 1 root root 6067 Oct 13 03:47 6379.log
-rw-r--r--. 1 root root 191 Oct 13 03:47 dump-6379.rdb
#rdb文件的大小已经变化了,时间也已经变化了,里面的内容也发生变化了
[root@localhost data]# cat dump-6379.rdb
#简单看下里面的内容,我们会发现在这里边,age后面接着又多了个addr,虽然我们看不太懂这个二进制文件里面的内容,但是勉强能看懂addr后面还接着一个beijing,基本上能够看得了,你说其他为什么看不了,数字在这里面会被组合成别的字符了,咱们不讨论这个问题。那么到这里呢,这个bgsave到这里就已经执行完了。注意bgsave是在后台执行的,ok这点一定要想清楚,具体的工作原理是什么样的呢?咱们来看一下。
RDB启动方式-bgsave指令工作原理

当我们在redis-cli执行bgsave这样的指令的时候,它redis-cli会发送一个指令给redis服务器,然后redis服务器会返回一个消息给redis-cli(Background saving started),返回的消息我们刚刚已经看到了,我想说的是这时候它有没有真正执行呢?没有。那什么时候执行的呢?在redis服务器返回消息Background saving started的时候,它会抽空去调用linux的fork函数,去生成一个子进程,也就是说它不参与我们redis序列的命令操作,它单独用一个子进程来维护它,让它去创建rdb文件同时去做完这件事情,做完以后,这个子进程会返回一个消息给redis服务器,告诉redis我们已经做完了。那是不是这样呢,我们能不能看到这个东西呢?我们可以去查看一下我们的日志文件。

指令:127.0.0.1:6379>bgsave

  1. redis-cli发送指令给到redis服务器
  2. redis服务器返回消息给到redis-cli,消息为Background saving started
  3. redis服务器调用fork函数生成子进程
  4. 子进程创建rdb文件
  5. 子进程创建完成rdb文件之后返回消息给到redis服务器,告诉redis已经创建完成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QmPcf81l-1622796414820)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210604132615143.png)]

#查看日志文件
#redis-server守护进程后台启动端
[root@localhost data]# ll
total 12
-rw-r--r--. 1 root root 6067 Oct 13 03:47 6379.log
-rw-r--r--. 1 root root 191 Oct 13 03:47 dump-6379.rdb
#进入到日志文件中
[root@localhost data]# cat 6379.log
#在该日志文件当中给出了一句话:background saving terminated with success
#即说明已经完成后台保存操作了。也就是说在这里边它会返回这样的一个信息,注意这个信息如果你是控制台的话,你能看到这个信息但是我们现在写到日志当中了,所以说现在就变成了这样一种格式,接着回来继续说

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x7ITlhtl-1622796414822)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210604133208304.png)]

注意:bgsave命令是针对 save阻塞问题做的优化。redis内部所有涉及到RDB操作都采用bgsave的方式,save命令可以放弃使用。

bgsave和save命令两者的工作原理不同。save命令是马上执行,并且加入到任务执行序列中,bgsave用的是什么?后台fork函数给我们创建的子进程来完成的,所以说完全两种不同的模式。非要使用save指令有没有问题?没有问题。save和bgsave,save它和bgsave用的保存的文件都是同一个文件,都是那一个快照文件。最后呢我们要说一下,bgsave有一个配置,前面的四个都见过了。因为save和bgsave都是用的rdb的形式,所以它们配置项共用。最后一个配置项是什么呢,stop-writes-on-bgsave-error yes,什么意思,就是说存的时候,后台存的时候它万一出错了怎么办,它问你这个操作停不停,挂上就行,那么这个配置就不往我的配置文件中添加了,了解一下就可以了。好了有关bgsave指令以及它的工作原理我们就讲到这里。

  • dbfilename dump.rdb

  • dir

  • rdbcompression yes

  • rdbchecksum yes

  • stop-writes-on-bgsave-error yes

    说明:后台存储过程中如果出现错误现象,是否停止保存操作

    经验:通常默认为开启状态

持久化-save配置与工作原理

RDB启动方式
反复执行保存指令,忘记了怎么办?不知道数据产生了多少变化,何时保存?

自动执行。

  • 谁:redis服务器发起指令(基于条件)
  • 什么时间:满足条件
  • 干什么事情:保存数据

第三种方式,自动执行的方式。

还是那三个问题。谁来干,什么时间干,干什么事情。

一、谁来干,注意自动执行是redis它自己干的,我们只要告诉它你要自动执行,它到时候就自动执行了,但是自动执行得有条件啊,不是随便做的。这是第一个

二、第二个什么时间干,你设置的条件只要一满足,它就开始干

三、第三个干什么,保存数据,不用问了,那你能猜想一下吗后台保存假如说用的是save或者bgsave指令,它用哪一个?记得一定是bgsave指令。因为bgsave不会影响到主进程的指令。

来看一下它的指令叫做什么。

RDB启动方式-save配置
  • 配置

    save second changes
    
  • 作用

    满足限定时间范围内 key的变化数量 达到指定数量即进行持久化

  • 参数

    second: 监控时间范围

    changes: 监控key的变化量

  • 位置

    在conf文件中进行配置

  • 范例

    save 900 1 
    save 300 10
    save 60 10000
    

对于自动执行的这种,它不可能是指令,因为它要提前告诉redis,所以说它用的是什么?配置。看一下它的配置叫什么,save second changes,什么意思,在second的时间范围内,如果监控到了changes数量次数的key发生了变化,那么它就进行持久化。比如说second为100,changes为10,则save 100 10,那么这一百秒内你执行了10个key的变化,不管你是在第5秒达成,还是在第99秒达成的,它都会去马上进行持久化。但是如果说要是超过了这个时间呢?比如说我设定到100秒内10个key进行变化再进行持久化,结果这一百秒内9个key发生了变化,到期了,没有key再变化了,那怎么办?重新计时,但是要记得,下一次持久化的话,它也会把整个都拷贝过去,它是一个快照的思想,所以说这一点明白就行了,它是控制频度么多个key数量达标了,它就要去变。那么它写在哪里?注意conf文件。

来看几个例子。

save 900 1什么意思,即十五分钟内只要变化一个我就存一个,你说要是这十五分钟内没有一个key变化呢?那我就不进行保存,相对来说它的频度会设置得相对低一些。

第二个 save 300 10,三百秒内10个key发生变化,也就是五分钟之内变化了5个我就存一次。

最后一个save 60 10000,每一分钟内只要有一万个发生了变化,我就存一次,那么这种设置呢通常是根据你的业务需要来设置的。

有一个小的细节大家可以看一下就是seconds大changes小,这是较为普遍设计的一种经验,来咱们一起看一下操作。

#为了不影响最终的实验效果,我们先把所有的东西都清理掉,先来看一下data中的数据,已经没有了只剩下一个日志了。
[root@localhost data]# ll
total 12
-rw-r--r--. 1 root root 10162 Oct 13 04:13 6379.log
[root@localhost data]# cd ..
#下边去进行修改配置文件
[root@localhost redis-4.0.0]# cd conf
[root@localhost conf]# vim redis-6379.conf
---------------------------------
port 6379
daemonize yes
logfile "6379.log"
dir /redis-4.0.0/data
dbfilename dump-6379.rdb
rdbcompression yes
rdbchecksum yes
#在这下边加一个东西
#为了做这个实验可以看出效果,我们给他配置成每十秒两个发生变化,我们让它持久化一次,这样我做的时候一个变化它是不会发生持久化的。
save 10 2 
---------------------------------
#进行保存,esc+:+wq 退出

[root@localhost conf]# clear
#启动一下对应的指令,因为现在是在conf目录下,所以就不再需要添加目录名了
[root@localhost conf]# redis-server 6379.conf
#启动起来了。通过redis-cli连接
[root@localhost conf]# 


#redis-cli客户端 启动起来它的客户端
[root@localhost redis-4.0.0]#  redis-cli
#下面给他添加数据
127.0.0.1:6379> set name 123
OK
127.0.0.1:6379> 

#redis-server守护进程后台启动端
#
[root@localhost conf]# cd..
[root@localhost redis-4.0.0]# cd data
#去看看这个rdb文件出来了没有
#现在还没有出来这个文件,因为在redis-cli端只改变了一个key
[root@localhost data]# ll
total 12
-rw-r--r--. 1 root root 11527 Oct 13 04:20 6379.log

#redis-cli端
#再来改变一个key
127.0.0.1:6379> set age 39
OK
127.0.0.1:6379> 


# 然后再回到data目录下看是否生成了rdb文件
[root@localhost data]# ll
total 16
-rw-r--r--. 1 root root 11852 Oct 13 04:20 6379.log
-rw-r--r--. 1 root root 177 Oct 13 04:20 dump-6379.rdb
# 现在data目录当中已经多了一个rdb文件了,两个key发生变化了,那么两个key发生变化以后,我们接着变再变化一个,看它rdb文件大小是否发生变化

#redis-cli
#注意我变的是原来已经存在的键key
127.0.0.1:6379> set age 40
OK
127.0.0.1:6379> 

#这时候再看到data目录下看rdb文件大小是否发生变化
[root@localhost data]# ll
total 16
-rw-r--r--. 1 root root 11852 Oct 13 04:20 6379.log
-rw-r--r--. 1 root root 177 Oct 13 04:20 dump-6379.rdb
#看清楚此时并没有发生变化

#redis-cli
127.0.0.1:6379> set name 321
OK
127.0.0.1:6379> 

#redis-cli执行完后看到data目录下rdb文件大小是否发生变化
[root@localhost data]# ll
total 16
-rw-r--r--. 1 root root 12177 Oct 13 04:21 6379.log
-rw-r--r--. 1 root root 178 Oct 13 04:21 dump-6379.rdb
#此时可以看到已经发生了变化,文件大小以及文件时间,为什么会发生变化,因为在redis-cli中存在有两个key发生了变化,所以这边就会进行了一个修改。如果在redis-cli中做这么一件事,看清楚如下

#redis-cli
127.0.0.1:6379> get name 
"321"
127.0.0.1:6379> get age
"40"
127.0.0.1:6379> 
#再去看data目录下的rdb文件大小是否有变化

#data目录下的rdb文件查看
[root@localhost data]# ll
total 16
-rw-r--r--. 1 root root 12177 Oct 13 04:21 6379.log
-rw-r--r--. 1 root root 178 Oct 13 04:21 dump-6379.rdb
#可以看到文件大小并没有发生变化。不用等了,它是不会发生变化的,因为只有key发生变化的时候,rdb文件才会发生变化。


#redis-cli 如果说当前客户端执行的是删除
127.0.0.1:6379> del name
(integer) 1
#那么此时data目录下的rdb文件会发生变化吗?它不会,因为del只有一个指令
127.0.0.1:6379> 

#data目录下的rdb文件观察
[root@localhost data]# ll
total 16
-rw-r--r--. 1 root root 12177 Oct 13 04:21 6379.log
-rw-r--r--. 1 root root 178 Oct 13 04:21 dump-6379.rdb

#此时redis-cli再执行一个修改/删除指令那么则rdb文件就会发生变化了
127.0.0.1:6379> set age 41
OK
127.0.0.1:6379> 
#当执行上述命令之后再去data目录下看rdb文件是否变化

#data目录下的rdb文件大小观察
[root@localhost data]# ll
total 16
-rw-r--r--. 1 root root 12502 Oct 13 04:22 6379.log
-rw-r--r--. 1 root root 169 Oct 13 04:22 dump-6379.rdb
#删除了一个key则rdb文件大小变小了
#好了到这里呢我们就能够观察出来save 配置它的执行是一个什么样的一个逻辑呀,就是在你的时间范围内,只要是有这么多个key发生了变化(修改/删除),它马上就去执行对应的指令。后台用的是bgsave,ok有关save配置对应的这样一种持久化的这种形式,我们就说到这里,最后我们来看一看它的工作原理。
RDB启动方式-save配置原理

当我们配置了save这样的一个配置以后呢,如果我们现在执行了三条指令,它redis-cli会发送给redis服务器,注意每一个指令回来以后都会返回一个结果,那么这个结果怎么样才会影响到这个save呢,几点。第一,它会对数据产生影响,比如说get不产生影响,这样的指令忽略掉。第二,它能真正的产生了影响,你说它产生了影响,但是它里面的值没有发生变化也不行,真正的产生影响。第三,注意它不进行数据的比对,什么意思?它不会拿现在的这个改变了的值去和你原来的那个值进行一个比对,比如说我对它进行了连续两次set同一个东西,那么它认为这个key发生了变化,ok吧,那这种情况之下,三合一下来,只要是影响了一个数据,它就认为产生了一个影响量,这就是它的整个工作原理。

127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> del name
(integer) 0
127.0.0.1:6379> lpop list1
(nil)

客户端redis-cli发送指令到redis服务器,redis服务器返回结果给redis-cli。

返回结果:

  1. [变量]影响数量+1
    1. 会对数据产生影响
    2. 真正产生了影响
    3. 不进行数据不对

注意:

save配置要根据实际业务情况进行设置,频度过高或者过低都会出现性能问题,结果可能是灾难性的

save配置中对于second与changes设置通常具有互补对应关系,尽量不要设置成包含性关系

save配置启动后执行的是bgsave操作

后台用的是bgsave指令。好了有关我们的rdb最后一种启动方式使用save配置的方式就讲到这里。

rdb启动方式:

  • 手动执行
    • save
    • bgsave
  • 自动执行
    • 在配置文件中进行save配置,后台启用的是bgsave

持久化-RDB三种启动方式对比与优缺点分析

RDB三种启动方式对比

方式save指令bgsave指令save配置
读写同步异步异步
阻塞客户端指令
额外内存消耗
启动新进程

三种rdb启动的形式我们都讲完了,save指令,bgsave指令和save配置。

那接下来咱们就要对这些方案进行一个横向对比了。首先我们先来看一下,save指令和bgsave指令都是指令,而save配置它和实际上后台走的还是bgsave指令,所以不看save配置,直接对比save指令与bgsave指令即可。

方式save指令bgsave指令
读写同步异步
阻塞客户端指令
额外内存消耗
启动新进程

对应的这四个点呢,其实都是针对某一方来说的。比如说save它是同步的,它跟着所有的命令走,那改良以后出的bgsave呢,它就是异步的,所以这点不同,其次,因为save命令跟着所有命令走所以save指令将会要阻塞客户端指令,那bgsave就不存在这样的事情,对应的第四个点你也能看明白了,为什么?因为bgsave它是怎么解决的,bgsave是起了一个新的子进程,所以说bgsave有新进程,而save没有启动新进程。同时bgsave相对来说它要消耗额外的内存,save不会。这是它们三者方式的对比。

RDB特殊启动方式
  • 全量复制

    • 在主从复制中详细讲解
  • 服务器运行过程中重启

    debug reload
    
  • 关闭服务器时指定保存数据

    shutdown save
    

除此之外,其实rdb还有其他的启动方式,我们在这里简单的了解一下即可。第一我们后面讲的主从复制中的全量复制,它会启动rdb的,简单说就是你想把一个redis中的数据复制给别人,你不先进行存储一下,那又怎么进行复制呢?另外一个你存储肯定是全数据呀,所以说rdb是它的解决方案。

第二个是重启,前面我也说过重启,但是没有用这个指令。在debug reload这个指令当中可以让服务器重启,这个时候它会启动rdb。

第三个关服务器的时候它也会保存。shutdown 前面咱们是不是一直使用linux的杀进程 kill -s 9 进程号的这种方式。在这儿关redis服务器的话可以用shutdown指令来进行关闭,关闭的时候要想保存,shutdown指令后面再加一个save参数。它就可以进行保存了。也会启动rdb。那么所有的启动方式我们都看完了,也比对完了。最后说一下rdb的优缺点。

rdb的启动方式

  • 手动启动
    • save指令
    • bgsave指令
    • debug reload指令
    • shutdown save指令
  • 自动启动
    • save配置,后台bgsave指令
  • 全量复制(采用了rdb)
RDB优点
  • RDB是一个紧凑压缩的二进制文件,存储效率较高
  • RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
  • RDB恢复数据的速度要比AOF快很多
  • 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复。
RDB缺点
  • RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据
  • bgsave指令每次运行时要执行fork操作创建子进程,要牺牲掉一些性能
  • redis的众多版本中未进行rdb文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象

现在再来看就可以综合的来说了,首先,RDB的存储效率高,因为它内部做了压缩compression ,二进制存储的,所以说它的存储效率要高一些,其次rdb存储的数据是某个时间点上的数据,不管你是save还是bgsave,执行命令那一刻对应的数据,它才会拍快照,而这后面到下一次执行之间的数据,实际上在rdb中是没有的,第三它的速度会比我们后面要讲的aof要快,最后一个,它通常用于灾难恢复,比如说我十点钟备份一下,十一点备份一下,十二点备份一下,你现在要做数据恢复,它就可以给你做,它有没有缺点呢,必然有。

就像刚才说的,十点备份一下,十一点备份一下,那十点四十五这个点的数据呢?没有备份,所以说,rdb它会丢数据,这是它的第一个缺点。第二个缺点是它要创建子进程,去做后台存储的话,会消耗CPU的一些性能,这个就看你能不能容忍了。最后一个也是比较尴尬的一点,就是redis的多版本之间的rdb文件版本不统一,不能相互混用,用redis2.0存储的rdb文件,用redis4.0去读取这个文件是读取不出来的。那怎么办呢,这事儿,也有解决方案,在redis2.0中你通过程序把我们的数据读取出来,保存到数据库或者其他文件中,然后把这个文件作为恢复成redis4.0那种数据的数据源即可。用这种形式来解决。当然这也只是一个没有办法的解决方案。因为redis没有做兼容。好了有关rdb所有的内容我们到这里就全部讲解完了。

持久化-AOF简介

目录

  • 持久化简介
  • RDB
  • AOF
  • RDB与AOF区别
  • 持久化应用场景

rdb已经学习完了,那接下来我们要学习第二种持久化方案AOF,在学习AOF之前我们先来看一看RDB目前所存在的一些问题。

RDB存储的弊端
  • 存储数据量较大,效率较低
    • 基于快照思想,每次读写都是全部数据,当数据量巨大时,效率非常低
  • 大数据量下的IO性能较低
  • 基于fork创建子进程,内存产生额外消耗
  • 宕机带来的数据丢失风险
解决思路
  • 不写全数据,仅记录部分数据
  • 改记录数据为记录操作过程
  • 对所有操作均进行记录,排除丢失数据的风险

首先第一个就是它的数据备份的这个思想是快照的思想,那就意味着什么,它的数据量比较大,你原来里面有一个G,你下次再备份,是以一个G为基础开始备份的。所以数据量大,数据量大带来的是什么,就是IO性能的下降。我每次就要有一个很长的时间。除此之外呢它还会用到一个fork的子进程,这样的话会产生一个额外的内存消耗。最后一个问题就是快照思想是某个时间点上的数据,我们无法做到即时的数据存储,因此rdb会丢失数据,也就是当你宕机的时候,有部分数据就会消失,除非你是时时刻刻都在不停的做快照,那么基于这些问题我们就想能不能解决呢?

问题肯定是要解决的,那么对应的解决思路是什么样的呢?我们可以比对这上面的问题来进行分析,首先第一,rdb里面存的是全数据,那我们要解决的话,我们首先不能存全数据,这样的话这个死循环就陷进去了,因为存全数据导致的性能下降,我们也无法解决。其次你不记录全数据,只记录部分数据,那你怎么知道这个部分数据从哪里开始到哪里结束呢?我们跳出这种思维方式,我们不记录数据,我们记录什么?记录你的操作记录。你操作了我就记录下来,操作过我就记录下来,这样的话我就不用担心我记录的数据是不是都完整了,再一个你前面宕机可能会丢失数据,现在呢,你的所有操作记录全部都记录下来,你的数据还会有丢失吗?我们想一想你每一个操作我都记录下来了,自然就不会有数据丢失了,所有说我们对它的操作进行记录并且是全部的操作,这样我们就降低了丢失数据的这种可能性,那么这些东西,就是AOF的一种工作思想。

来看一下什么是AOF

AOF概念
  • AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行aof文件中命令达到恢复数据的目的。与rdb相比可以简单描述为 改记录数据为记录数据产生的过程
  • aof的主要作用是解决了数据持久化的实时性,目前已经是redis持久化的主流方式。

aof是什么呢,append only file, 我们只记录追加的东西,以独立日志的方式来记录你每次的操作过程,不管你是什么样的操作,我都记下来,但是你注意一点,如果你的这个操作对于数据没有影响,那记录它有用吗?是没有用的,把操作记录记录下来,那下一次你一旦进行重启或者执行我们的数据恢复的时候,我就把你操作过的过程再执行一遍即可,这样的话就比较的快捷一些,与rdb相比,它的差别在于rdb记录快照数据,aof记录数据产生的过程。那么需要注意,aof主要解决的是数据持久化的一个实时性,目前它已经成为了redis持久化的主流方式。那有人说这个aof和rdb我应该用哪一个呢?首先明确一点,我们优先用aof,在这一章节的最后我们会去分析这两种持久化方案。

好了有关aof的基本介绍我们就说到这里。

持久化-AOF持久化策略基本操作

AOF写数据过程

在进行具体的aof操作之前呢,我们先来说一下aof整个写数据的过程。

当我们客户端redis-cli发出一条指令给我们redis服务器的时候,我们redis服务器接收到了这一条指令,redis服务器此时并没有马上进行记录,而是将这条命令放到了一个临时的区域当中,这个区域是什么呢,就是aof它所要操作的这些写命令对应的一个存储的缓冲区,把命令先放到这个aof写命令缓冲区当中,如果还有指令到达redis服务器中,也是先将该指令放到该缓冲区当中,那这些指令干嘛的呢,最终是为了生成我们的.aof的存储文件时候用的,到了一定阶段以后,将这些命令全部同步到我们的aof文件当中即可。那这个时候就存在一个问题了,什么问题,我们一次写过去多少条?我们多久写一次呢?这些问题如果你不搞清楚的话,你就想着aof到底是怎么工作的,于是在aof中,就给我们提供了三种方式来控制这些命令,到这个存储文件当中。

127.0.0.1:6379> set name itheima

以上指令被redis-cli发送到redis服务器中,redis服务器此时不会立即将该命令放到aof文件当中,而是将该命令放入到一个aof写命令刷新缓存区,即aof写命令缓冲区中,到了一定时间,满足一定条件之后就将这个缓冲区当中的命令同步到aof文件当中去。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XlssTX46-1622796414823)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210604160018553.png)]

那对应的是什么呢?

这就是下面咱们要说的aof写数据的三种策略。

AOF写数据三种策略(appendfsync)
  • always(每次)
    • 每次写入操作均同步到aof文件中,数据零误差性能较低,不建议使用
  • everysec(每秒)
    • 每秒将缓冲区中的指令同步到aof文件中,数据准确性较高性能较高,建议使用,也是默认配置
    • 在系统突然宕机的情况下丢失一秒内的数据
  • no(系统控制)
    • 由操作系统控制每次同步到aof文件的周期,整体过程不可控

分别是always、everysec和no,第一个always,什么意思,每次,什么概念呢就是你这边只要来一个命令,我就把它放到aof文件当中去,那你想一想首先它是不是每一个指令都记录了?但是性能呢它会比较低,一次来一个指令写一下,一次来一个指令写一下,想过没有,当你的指令特别多的时候,一秒钟十几万的指令过来的时候,你怎么办?你的整个io就在占用大量的时间,你的CPU就在处理大量这一块的东西,你的业务呢?恐怕就会要被占用时间了。所以说always这种策略只是一种方案,那对应的还有就是说别那么频繁,我们用第二种everysec,什么呢?everysecond每一秒,它用每一秒去存储一次,这样我们根据刚才的想法来想一想,每次存储一个比较多,次数太频繁,那好我降低一下频度,怎么降?我一秒给你存储一次,这样一秒存一次一秒存一次,一秒钟有多少个指令呢,不管它,一秒钟十个指令就十个存一下,一百个就一百个存一下,九十七个就九十七个存一下,这样说首先我们的IO性能写的速度就降低了,它不会抢太多的CPU时间了,那么准确性怎么样呢?也还不错。因为它的数据是一秒一存储,一秒一存储,如果你redis服务器出问题了,那它丢多少数据?一秒内的数据。咱们不考虑那个写的过程当中出问题,我们就说写成功了,当我们的数据发生了一个问题的时候,顶多顶多就是丢失一秒内的数据,相比之下还好吧,你说你的redis长年累月的运行,丢失一秒的数据也还好。第三种是什么呢?no。注意no不是不管,是由系统控制的,这种是由操作系统来控制它,什么时间或者多少来同步到我们的aof文件中一次,那整个过程就不归我们管辖了。那这三个东西相对比一下,我们可以找一下它们三者的特征。

第一个always,它的数据最准确,因为它是来一条写一条,那么第二个everysec,它的数据准确性相对来说是较高的,因为它毕竟想丢数据也就丢一秒内的数据,一点点,那么我们从性能上来看,always的性能就比较低了,它一次一写一次一写,那everysec呢,性能就相对来说就高一些,那对于第三种方案no,系统控制,这个不受我们控制我们就没法儿分析它了。所以呢我们就给出了这样一种使用方案,第一种always不建议使用,为什么不建议,除非你对数据的准确性特别高否则我们不建议使用,而第二种everysec则建议使用,同时也是redis aof的一个默认配置,也就是当你不写这个配置的时候,它就按照everysec来进行配置的,那么这些东西该配置在什么地方呢?就是上面的这一项了appendfsync

AOF功能开启
  • 配置

    appendonly yes|no
    
  • 作用

    是否开启AOF持久化功能,默认为不开启状态

  • 配置

    appendfsync always|everysec|no
    
  • 作用

    AOF写数据策略

当我们配置的时候,我们要想使用aof功能,两步,第一步先告诉我们的配置文件,你要使用aof,appendonly yes,要开启成yes,默认是no。这是第一个。

第二个我们要把它的一个aof策略给他配置上,always、everysec、no我们选择一个配置项值配置到appendfsync后面。

下面进入演示的环节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值