精华内容
下载资源
问答
  • MySQLOracle都是属性关系数据库。 特点 关系数据库关系数据库 存储介质 以文件方式保存在硬盘中 通常只存储在内存中,服务器关闭数据会部分或全部丢失 优点 数据库可以永久保存 存取速度非常...
  • 一、redis介绍Redis是一个速度非常快关系数据库,它可以存储键(key)5种不同类型值(value)之间映射(mapping),可以将存储在内存键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用...

    内容来自《redis实战》。http://redisinaction.com/preview/chapter1.html#id7

    一、redis介绍

    Redis是一个速度非常快的非关系数据库,它可以存储键(key)与5种不同类型的值(value)之间的映射(mapping),可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片来扩展写性能。Redis是一个远程内存数据库。

    1、与memcached比较

    memcached是高性能键值缓存服务器,这两者都可用于存储键值映射,彼此的性能也相差无几,但是Redis能够自动以两种不同的方式将数据写入磁盘,并且Redis除了能存储普通的字符串键之外,还可以存储其他4种数据结构,而memcached只能存储普通的字符串键。这些及其他不同使得Redis可以用于解决更为广泛的问题,既可以作为主数据库(primary database)使用,又可以作为其他存储系统的辅助数据库(auxiliary database)使用。

    2、各种数据库特性与功能

    这里写图片描述

    3、持久化

    在使用类似Redis这样的内存数据库时,一个首先要考虑的问题就是“当服务器被关闭时,服务器存储的数据将何去何从呢?”

    Redis拥有两种不同形式的持久化方法,它们都可以用小而紧凑的格式将存储在内存中的数据写入到磁盘:

    第一种持久化方法为时间点转储(point-in-time dump),转储操作既可以在“指定时间段内有指定数量的写操作执行”这一条件被满足时执行,又可以通过调用两条转储到磁盘(dump-to-disk)命令中的任何一条来执行;

    第二种持久化方法将所有修改了数据库的命令都写入到一个只追加(append-only)文件里面,用户可以根据数据的重要程度,将只追加写入设置为从不同步(sync)、每秒钟同步一次或者每写入一个命令就同步一次。

    4、主从复制

    尽管Redis的性能很好,但受限于Redis的内存存储设计,有时候只使用一台Redis服务器可能没有办法处理所有请求。因此,为了扩展Redis的读性能,并为Redis提供故障转移(failover)支持,Redis实现了主从复制特性:

    执行复制的从服务器会连接上主服务器,接收主服务器发送的完整数据库的初始副本(copy);之后主服务器执行的写命令,都会被发送给所有连接着的从服务器去执行,从而实时地更新从服务器的数据集。因为从服务器包含的数据会不断地进行更新,所以客户端可以向任意一个从服务器发送读请求,以此来避免对主服务器进行集中式的访问。

    5、redis数据结构

    Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为STRING(字符串)、LIST(列表)、SET(集合)、HASH(散列)和ZSET(有序集合)。

    这里写图片描述

    二、常用操作

    1、字符串操作

    这里写图片描述

    例如:redis 127.0.0.1:6379> set hello world#将键hello的值设置为world

    2、列表操作

    列表里的元素可以重复,且是有序存储。
    LPUSH命令和RPUSH命令分别用于将元素推入到列表的左端(left end)和右端(right end);LPOP命令和RPOP命令分别用于从列表的左端和右端弹出元素;LINDEX命令用于获取列表在给定位置上的一个元素;LRANGE命令用于获取列表在给定范围上的所有元素。

    这里写图片描述

    除了上面提到的命令之外,Redis列表还拥有从列表里面移除元素的命令、将元素插入到列表中间的命令、将列表修剪至指定长度(相当于从列表的其中一端或者两端移除元素)的命令,以及其他一些命令。

    3、集合操作

    Redis的集合和列表都可以存储多个字符串,它们之间的不同在于,列表可以存储多个相同的字符串,而集合则通过使用散列表来保证自己存储的每个字符串都是各不相同的(这些散列表只有键,但没有与键相关联的值)。集合使用无序(unordered)方式存储元素。

    这里写图片描述

    另外,SINTER、SUNION、SDIFF三个命令分别执行常见的交集计算、并集计算和差集计算。

    4、散列操作

    Redis的散列可以存储多个键值对之间的映射。和字符串一样,散列存储的值既可以是字符串又可以是数字值,并且用户同样可以对散列存储的数字值执行自增操作或者自减操作。

    这里写图片描述

    5、有序集合操作

    有序集合和散列一样,都用于存储键值对:其中有序集合的每个键称为成员(member),都是独一无二的,而有序集合的每个值称为分值(score),都必须是浮点数。有序集合是Redis里面唯一既可以根据成员访问元素(这一点和散列一样),又可以根据分值以及分值的排列顺序来访问元素的结构。

    这里写图片描述

    这里写图片描述

    展开全文
  • 使用快照AOF将Redis数据持久化到硬盘中转自https://blog.csdn.net/xlgen157387/article/details/61925524前言我们知道Redis是一款内存服务器,...因此,我们需要向传统的关系数据库一样对数据进行备份,将Red...

    使用快照和AOF将Redis数据持久化到硬盘中

    转自https://blog.csdn.net/xlgen157387/article/details/61925524


    前言

    我们知道Redis是一款内存服务器,就算我们对自己的服务器足够的信任,不会出现任何软件或者硬件的故障,但也会有可能出现突然断电等情况,造成Redis服务器中的数据失效。因此,我们需要向传统的关系型数据库一样对数据进行备份,将Redis在内存中的数据持久化到硬盘等非易失性介质中,来保证数据的可靠性。

    将Redis内存服务器中的数据持久化到硬盘等介质中的一个好处就是,使得我们的服务器在重启之后还可以重用以前的数据,或者是为了防止系统出现故障而将数据备份到一个远程的位置。

    还有一些场景,例如:

    对于一些需要进行大量计算而得到的数据,放置在Redis服务器,我们就有必要对其进行数据的持久化,如果需要对数据进行恢复的时候,我们就不需进行重新的计算,只需要简单的将这台机器上的数据复制到另一台需要恢复的Redis服务器就可以了。
    • 1

    Redis给我们提供了两种不同方式的持久化方法:快照(Snapshotting) 和 只追加文件(append-only-file)

    (1)名词简介

    快照(RDB):就是我们俗称的备份,他可以在定期内对数据进行备份,将Redis服务器中的数据持久化到硬盘中;

    只追加文件(AOF):他会在执行写命令的时候,将执行的写命令复制到硬盘里面,后期恢复的时候,只需要重新执行一下这个写命令就可以了。类似于我们的MySQL数据库在进行主从复制的时候,使用的是binlog二进制文件,同样的是执行一遍写命令;

    (2)快照持久化通用的配置:

    save 60 1000  #60秒时间内有1000次写入操作的时候执行快照的创建
    stop-writes-on-bgsave-error no  #创建快照失败的时候是否仍然继续执行写命令
    rdbcompression yes  #是否对快照文件进行压缩
    dbfilename dump.rdb   #如何命名硬盘上的快照文件
    dir ./  #快照所保存的位置
    • 1
    • 2
    • 3
    • 4
    • 5

    (3)AOP持久化配置:

    appendonly no  #是否使用AOF持久化
    appendfsync everysec  #多久执行一次将写入内容同步到硬盘上
    no-appendfsync-on-rewrite no #对AOF进行压缩的时候能否执行同步操作
    auto-aof-rewrite-percentage 100  #多久执行一次AOF压缩
    auto-aof-rewrite-min-size 64mb  #多久执行一次AOF压缩
    dir ./ #AOF所保存的位置
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    需要注意的是:这两种持久化的方式既可以单独的使用,也可以同时使用,具体选择哪种方式需要根据具体的情况进行选择。

    快照持久化

    快照就是我们所说的备份。用户可以将Redis内存中的数据在某一个时间点进行备份,在创建快照之后,用户可以对快照进行备份。通常情况下,为了防止单台服务器出现故障造成所有数据的丢失,我们还可以将快照复制到其他服务器,创建具有相同数据的数据副本,这样的话,数据恢复的时候或者服务器重启的时候就可以使用这些快照信息进行数据的恢复,也可以防止单台服务器出现故障的时候造成数据的丢失。

    但是,没我们还需要注意的是,创建快照的方式,并不能完全保证我们的数据不丢失,这个大家可以很好的理解,因为快照的创建时定时的,并不是每一次更新操作都会创建一个快照的。系统发生崩溃的时候,用户将丢失最近一次生成快照之后更改的所有数据。因此,快照持久化的方式只适合于数据不经常修改或者丢失部分数据影响不大的场景。

    一、创建快照的方式:

    (1)客户端通过向Redis发送BGSAVE 命令来创建快照。

    使用BGSAVE的时候,Redis会调用fork来创建一个子进程,然后子进程负责将快照写到硬盘中,而父进程则继续处理命令请求。

    使用场景:

    如果用户使用了save设置,例如:save 60 1000 ,那么从Redis最近一次创建快照之后开始计算,当“60秒之内有1000次写入操作”这个条件满足的时候,Redis就会自动触发BGSAVE命令。

    如果用户使用了多个save设置,那么当任意一个save配置满足条件的时候,Redis都会触发一次BGSAVE命令。

    (2)客户端通过向Redis发送SAVE 命令来创建快照。

    接收到SAVE命令的Redis服务器在快照创建完毕之前将不再响应任何其他命令的请求。SAVE命令并不常用,我们通常只在没有足够的内存去执行BGSAVE命令的时候才会使用SAVE命令,或者即使等待持久化操作执行完毕也无所谓的情况下,才会使用这个命令;

    使用场景:

    当Redis通过SHUTDOWN命令接收到关闭服务器的请求时,或者接收到标准的TERM信号时,会执行一次SAVE命令,阻塞所有的客户端,不再执行客户端发送的任何命令,并且在执行完SAVE命令之后关闭服务器。

    二、使用快照持久化注意事项:

    我们在使用快照的方式来保存数据的时候,如果Redis服务器中的数据量比较小的话,例如只有几个GB的时候。Redis会创建子进程并将数据保存到硬盘里边,生成快照所需的时间比读取数据所需要的时间还要短。

    但是,随着数据的增大,Redis占用的内存越来越大的时候,BGSAVE在创建子进程的时候消耗的时间也会越来越多,如果Redis服务器所剩下的内存不多的时候,这行BGSAVE命令会使得系统长时间地停顿,还有可能导致服务器无法使用。

    各虚拟机类别,创建子线程所耗时间:

    这里写图片描述

    因此,为了防止Redis因为创建子进程的时候出现停顿,我们可以考虑关闭自动保存,转而通过手动的方式发送BGSAVE或者SAVE来进行持久化,

    手动的方式发送BGSAVE也会出现停顿的现象,但是我们可以控制发送该命令的时间来控制出现停顿的时候不影响具体的业务请求。

    另外,值得注意的是,在使用SAVE命令的时候,虽然会一直阻塞Redis直到快照生成完毕,但是其不需要创建子进程,所以不会向BGSAVE一样,因为创建子进程而导致Redis停顿。也正因为如此,SAVE创建快照的速度要比BGSAVE创建快照的速度更快一些。

    创建快照的时候,我们可以在业务请求,比较少的时候,比如凌晨三、四点,通过手写脚本的方式,定时执行。

    AOF持久化

    AOF持久化会将被执行的写命令写到AOF文件的末尾,以此来记录数据发生的变化。这样,我们在恢复数据的时候,只需要从头到尾的执行一下AOF文件即可恢复数据。

    一、打开AOF持久化选项

    我们可以通过使用如下命令打开AOF:

    appendonly yes
    • 1

    我们,通过如下命令来配置AOF文件的同步频率:

    appendfsync everysec/always/no
    • 1

    二、appendfsync同步频率的区别

    appendfsync同步频率的区别如下图:

    这里写图片描述

    (1)always的方式固然可以对没一条数据进行很好的保存,但是这种同步策略需要对硬盘进行大量的写操作,所以Redis处理命令的速度会受到硬盘性能的限制。

    普通的硬盘每秒钟只能处理大约200个写命令,使用固态硬盘SSD每秒可以处理几万个写命令,但是每次只写一个命令,这种只能怪不断地写入很少量的数据的做法有可能引发严重的写入放大问题,这种情况下降严重影响固态硬盘的使用寿命。

    (2)everysec的方式,Redis以每秒一次的频率大队AOF文件进行同步。这样的话既可以兼顾数据安全也可以兼顾写入性能。

    Redis以每秒同步一次AOF文件的性能和不使用任何持久化特性时的性能相差无几,使用每秒更新一次 的方式,可以保证,即使出现故障,丢失的数据也在一秒之内产生的数据。

    (3)no的方式,Redis将不对AOF文件执行任何显示的同步操作,而是由操作系统来决定应该何时对AOF文件进行同步。

    这个命令一般不会对Redis的性能造成多大的影响,但是当系统出现故障的时候使用这种选项的Redis服务器丢失不定数量的数据。

    另外,当用户的硬盘处理写入操作的速度不够快的话,那么缓冲区被等待写入硬盘的数据填满时,Redis的写入操作将被阻塞,并导致Redis处理命令请求的速度变慢,因为这个原因,一般不推荐使用这个选项。

    三、重写/压缩AOF文件

    随着数据量的增大,AOF的文件可能会很大,这样在每次进行数据恢复的时候就会进行很长的时间,为了解决日益增大的AOF文件,用户可以向Redis发送BGREWRITEAOF 命令,这个命令会通过移除AOF文件中的冗余命令来重写AOF文件,是AOF文件的体检变得尽可能的小。

    BGREWRITEAOF的工作原理和BGSAVE的原理很像:Redis会创建一个子进程,然后由子进程负责对AOF文件的重写操作。

    因为AOF文件重写的时候汇创建子进程,所以快照持久化因为创建子进程而导致的性能和内存占用问题同样会出现在AOF文件重写的 时候。

    四、触发重写/压缩AOF文件条件设定

    AOF通过设置auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 选项来自动执行BGREWRITEAOF。

    其具体含义,通过实例可以看出,如下配置:

    auto-aof-rewrite-percentage 100 
    auto-aof-rewrite-min-size 64mb
    • 1
    • 2

    表示当前AOF的文件体积大于64MB,并且AOF文件的体积比上一次重写之后的体积变大了至少一倍(100%)的时候,Redis将执行重写BGREWRITEAOF命令。

    如果AOF重写执行的过于频繁的话,可以将auto-aof-rewrite-percentage 选项的值设置为100以上,这种最偶发就可以让Redis在AOF文件的体积变得更大之后才执行重写操作,不过,这也使得在进行数据恢复的时候执行的时间变得更加长一些。

    验证快照文件和AOF文件

    无论使用哪种方式进行持久化,我们在进行恢复数据的时候,Redis提供了两个命令行程序:

    redis-check-aof
    redis-check-dump
    • 1
    • 2

    他们可以再系统发生故障的时候,检查快照和AOF文件的状态,并对有需要的情况对文件进行修复。

    如果用户在运行redis-check-aof命令的时候,指定了--fix 参数,那么程序将对AOF文件进行修复。

    程序修复AOF文件的方法很简单:他会扫描给定的AOF文件,寻找不正确或者不完整的命令,当发现第一个出现错误命令的时候,程序会删除出错命令以及出错命令之后的所有命令,只保留那些位于出错命令之前的正确命令。大部分情况,被删除的都是AOF文件末尾的不完整的写命令。

    总结

    上述,一起学习了两种支持持久化的方式,一方面我们需要通过快照或者AOF的方式对数据进行持久化,另一方面,我们还需要将持久化所得到的文件进行备份,备份到不同的服务器上,这样才可以尽可能的减少数据丢失的损失。


    参考文章:

    1、Redis in Action - [美] Josiah L.Carlsono


    展开全文
  • 什么是NoSQL数据库

    2014-07-21 23:24:20
    关系数据库和NoSQL数据库 什么是NoSQL 大家有没有听说过“NoSQL”呢?近年,这个词极受关注。看到“NoSQL”这个词,大家可能会误以为是“No!SQL”缩写,并深感愤怒:“SQL怎么会没有必要了呢?”但实际上,它是...
  • SQL Server是由Microsoft开发推广的关系数据库管理系统(DBMS),它最初是由Microsoft、SybaseAshton-Tate三家公司共同开发的。SQL Server 2000是Microsoft公司于2000年推出的最新版本。 SQL Server 特点:  1....
  • Redis数据结构探究

    2018-07-03 16:48:15
    1、其他数据库的对比 最近系统中引入了Redis,在应用中...memcache也可以用来存储键值映射,同是对内存操作,Redis性能差别不大,但是Redis具备以两种形式将数据写入硬盘的能力,并且除了存储普通的字符串键...

    1、与其他数据库的对比

    最近系统中引入了Redis,在应用中发现Reids具有关系型数据库或其他缓存服务器所不具备的优点。
    与关系型数据库如Mysql相比,Reids属于非关系型数据库,类似于Nosql,不同数据之间不需要有关联关系。
    memcache也可以用来存储键值映射,同是对内存操作,和Redis性能差别不大,但是Redis具备以两种形式将数据写入硬盘的能力,并且除了存储普通的字符串键值外,还可以存储其他四种数据结构,而memcache只能存储字符串键。所以Redis可以用来解决更广泛的问题,而且不只可以用来当做缓存数据库,更可以用作主数据库使用。

    2、Redis的五种数据类型

    Redis可以存储五种键和数据类型间的映射,分别是STRING、LIST、SET、HASH、ZSET,其中STRING、LIST、SET、HASH在大多数编程语言中都存在,在实现和作用上也比较相似。另外ZSET是特有的一种数据结构,是一种有序集合。
    以下是五种数据类型之间的对比和特点。

    结构类型 结构存储的值 结构操作
    STRING 字符串、整数、浮点数 可以对字符串或字符串一部分执行操作,对整数和浮点数进行++ –操作
    LIST 链表,链表的每个节点包含一个字符串 可以在链表两端进行push pull(起到了栈的作用),根据偏移量进行trim,读取单个或多个元素,根据值查找或删除元素
    SET 无序集合 添加/获取/移除元素,判断是否存在,交差并集合,随机获取元素
    HASH 无序散列表 添加、移除、获取键值对,获取所有键值对
    ZSET 有序集合,由字符串和分数组成,元素排列顺序根据分值 添加、获取、删除元素,根据分值获取元素

    2.1 STRING

    Redis的字符串映射的键和值都是字符串类型,可以存储字符串、整数或浮点数。和memcache的键值对作用相同。除了普通字符串类型,在存储一些复杂结构时,比如本次在系统中存储一个java对象,就是将对象序列化为字符串进行储存,另外,也可以将对象序列化为json或xml进行存储。
    一般STRING类型有以下应用场景:

    • 缓存,存储基础数据信息(文章、用户、记录等)。仅当update/insert时访问数据库并更新缓存,其他时候只访问缓存,可以显著减轻数据库压力。
    • 用作session服务器,一般服务器集群中共享session会存储在数据库、session服务器、redis中,存取较快。
    • 计数器等操作频繁的数据请求,因为STRING类型可以存储整数或浮点数并可以自增,所以用作计数器、pingback等非常方便。

    2.2 LIST

    LIST就是我们经常用到的数据结构中的队列,Redis的LIST是双端队列,两端都可以进行Push和pull操作,所以也可以当做栈来使用,另外还可以获取一定范围内的列表。
    LIST有以下应用场景:

    • 分布式系统中服务间调用可以使用LIST实现消息队列,实现异步调用,使应用间解耦。
    • 高并发场景下可以使用LIST实现限流。
    • 文章分页或者是有序的列表数据可以使用LIST,因为可以在某个范围内存取元素。

    2.3 HASH

    上文中提到了STRING可以用来存储序列化的对象,但是如果这个对象需要进行操作的话,需要先解析再修改再序列化保存,无法直接修改。而HASH类型可以解决这个问题,在Redis中,HASH结构可以解决这个问题,它的键也是一个键值对,用户可以直接修改HASH结构中某个属性的值。所以适合存储对象。
    HASH有以下应用场景:

    • 存储用户数据,用户基础数据是请求频率较高的,但是属性较多且经常需要修改,所以可以存储在HASH,修改时update某个属性就可以。

    2.4 SET

    SET是数据结构中的集合,与列表不同的是它不保存重复数据,并且元素无序,所以不能获取一定范围内的元素,也不能根据索引获取。Redis支持对集合进行交并差集计算,在很多场景下都可以发挥作用。
    SET有以下应用场景:

    • 数据排重,比如记录今天访问的用户,可以使用集合。
    • 标签操作,系统中有个功能是打标签,每打一个标签,可以将该数据保存在以标签id为key的set中,展示时直接展示该set。
    • 用户关系操作,比如计算用户的共同好友等。

    2.5 ZSET

    有序集合是一种特殊的集合,它既具备集合不重复元素的特点,又可以进行排序。但它和list不同的是,它不是根据下标排序,所以排序不固定,而是它的value中包含一个分值,分值可以是分数、访问量等等,根据自定义类别进行排序。
    ZSET有以下应用场景:

    • 排行榜,排序操作最常用的应用就是排行榜,比如考试分数、访问量、点赞量。考虑的一个应用场景是在wiki中的精选文章中,对文章进行排序。因为精选文章相对固定但需要实时变动,应用ZSET比较合适。

    3、底层数据结构的实现

    我们知道Redis是使用ANSI C实现的,那它是怎么实现的集合等复杂数据结构,比较令人好奇,在阅读了《Redis设计与实现》这本书后,得到了比较准确的答案。首先我们需要了解一下Redis中使用到的数据结构。

    3.1 简单动态字符串

    最开始以为Redis是使用c++中的char数组来存储字符串类型,其实并不是这样,它定义了一个名为simple dynamic string(SDS)的结构体用来保存字符串类型,结构如下:

    struct sdshdr{
        int len;
        int free;
        int buf[];
    }

    其中:

    • len:buf中已用长度
    • free:bug剩余可用长度
    • buf[] : 字符数组

    我们存储的字符串就是存储在buf数组中,这样做的原因是char[]并不能满足Redis的操作需求,或是会带来较大的性能消耗,比如append,获取长度等等。像一些高级语言,也普遍有这种实现方式,像之前在阅读PHP数据结构源码时,string类型也是由数组和一个标志长度的int值实现。这样获取长度的复杂度就是O(1)。另外还有一些好处:

    • 防止缓冲区溢出
      字符串长度增加时,如果内存相邻地址已有内容,则会发生缓冲区溢出的现象,而Redis在扩展字符串时,会先检查free长度,如果不够时,会先拓展空间。
    • 减少内存分配次数
      SDS的扩展策略是小于1MB时,每次扩展到之前的二倍大小,大于1MB时,每次扩展1MB,所以不需要每次变化都重新分配内存。另外由于释放空间时采用惰性空间释放,减少了内存分配次数。
    • 惰性空间释放
      SDS释放空间时并不真正释放内存空间,而是修改free的值,既能避免内存泄露,又减少内存分配次数。
    • 二进制安全
      c字符串末尾默认是空字符,所以在首次读入空字符时会被认为字符串结束。而SDS记录了len长度,可以通过长度获取内容,有空字符也不影响,所以可以用来存储二进制数据。

    简单动态字符串是Redis最重要的数据结构,键值等字符串类型是使用它,另外还有AOF模块中的AOF缓冲区,以及客户端状态中的输入缓冲区也是由它实现。

    3.2 链表

    Redis中的LIST实现之一就是链表的。由链表和节点两种数据结构组成,节点用来存储数据和指针,链表结构封装了一些复制和删除节点的操作。
    下面是节点的结构体:

    typedef struct listNode{
        struct listNode *prev;
        struct listNode *next;
        void *value;
    }listNode;

    普通链表节点一般只有一个指针指向下一个节点,而这里面有pre和next两个指针,实现了一个双向链表。
    下面是链表结构体:

    typedef struct list{
        listNode *head;
        listNode *tail;
        unsigned long len;
        void *(*dup) (void *ptr)
        void *(*free)(void *ptr)
        int (*match)(void *ptr,void *key);
    }list;

    list结构体中除了包含head头结点,tail尾节点,len长度外,还封装了复制节点、删除节点、匹配节点的方法。

    3.3 hashtable

    Redis中HASH的实现方式之一是hashtable,由dict和dictht两种数据结构实现。
    其中字典dict的数据结构:

    typedef struct dict {  
        dictType *type;  
        void *privdata;  
        dictht ht[2];  
        long rehashidx; /* rehashing not in progress if rehashidx == -1 */  
        int iterators; /* number of iterators currently running */  
    } dict; 

    type 属性 和privdata 属性是针对不同类型的键值对,为创建多态字典而设置的。ht 属性是一个包含两个项(两个哈希表)的数组。指向了两个哈希表dictht。

    typedef struct dictht {  
        dictEntry **table;  
        unsigned long size;  
        unsigned long sizemask;  
        unsigned long used;  
    } dictht; 

    其中dictht中的table是用来存储kv元素的,每个dictEntry包含一对kv。
    最后,哈希表节点dictEntry结构定义为:

    typeof struct dictEntry{
       void *key;
       union{
          void *val;
          uint64_tu64;
          int64_ts64;
       }
       struct dictEntry *next;
    }

    其中的next指针是为了解决hash冲突时,使用了链地址法组成链表。在此不对如何解决hash冲突和使用的散列算法进行深入讨论。
    如图所示:
    这里写图片描述
    图片来自引用
    HASH的另一种实现方式是ziplist。

    3.4 intset

    Redis中SET的实现方式有两种,其中一种是hashtable,在上文中已经有过了解。另外一种是intset,这是一个整数集合,里面存的为某种同一类型的整数,支持如下三种长度的整数:

    #define INTSET_ENC_INT16 (sizeof(int16_t))  
    #define INTSET_ENC_INT32 (sizeof(int32_t))  
    #define INTSET_ENC_INT64 (sizeof(int64_t))  

    intset结构体为:

    typedef struct intset{
        //编码方式
        uint32_t enconding;
        //集合包含的元素数量
        uint32_t length;
        //保存元素的数组
        int8_t contents[];
    }intset;

    其中里面的数据按照从大到小的元素排列。并且存储的类型由encoding决定。在集合中查找元素的复杂度为O(logN)。但插入时设计到从16位升级到32位或64位,所以复杂度不一定。并且升级后不能再降级。

    3.5 skiplist

    Redis的ZSET实现方式之一是跳跃表,另一种是ziplist。

    跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。跳跃表是一种随机化的数据,跳跃表以有序的方式在层次化的链表中保存元素,效率和平衡树媲美 ——查找、删除、添加等操作都可以在对数期望时间下完成,并且比起平衡树来说,跳跃表的实现要简单直观得多。

    跳跃表主要由链表和节点组成,下面是链表zskiplist的数据结构。

    typedef struct zskiplist {  
        struct zskiplistNode *header, *tail;
        unsigned long length;  
        //最大节点成熟
        int level;  
    } zskiplist;  

    可以看到,和普通链表不同的是,多了一个level用来记录表中层数最大的节点的层数。
    下面是节点的结构体:

    typedef struct zskiplistNode {  
        // member  
        robj *obj;  
        // 分值  
        double score;  
        // 后退指针  
        struct zskiplistNode *backward;  
        // 层  
        struct zskiplistLevel {  
            // 前进指针  
            struct zskiplistNode *forward;  
            // 这个层跨越的节点数量  
            unsigned int span;  
        } level[];  
    } zskiplistNode;  

    其中除了value和分数score外,还包含了一个level[]数组,这就是每个节点里的分层指针数组。
    如图所示:
    这里写图片描述
    图片来自引用
    其中每个节点的层数都是1到32的随机数,节点间是按照分值大小来进行排序。

    3.6 ziplist

    这是一种压缩列表,在LIST和HASH中使用,因为它保存在连续的内存空间中,所以比价节省内存空间,但在插入时每次都需要重新分配空间。
    如图所示:
    这里写图片描述
    图片来自引用
    其中,包含如下属性:

    • zlbytes:用于记录整个压缩列表占用的内存字节数
    • zltail:记录要列表尾节点距离压缩列表的起始地址有多少字节
    • zllen:记录了压缩列表包含的节点数量。
    • entryX:要说列表包含的各个节点
    • zlend:用于标记压缩列表的末端

    3.7 Redis对象的实现

    上面讲解了Reids实现中使用到的数据结构,其中Redis中的每个对象都不是由固定的数据结构实现,而是会根据数据类型大小选择不同的实现方式,以下为对应表。

    Redis对象 实现方式
    STRING int 实现
    embstr编码的简单动态字符串(SDS)实现
    SDS实现
    LIST ziplist压缩列表实现
    链表实现
    HASH ziplist实现
    字典hashtable实现
    SET intset整数集合实现
    hashtable实现
    ZSET ziplist实现
    跳表skiplist、hashtable实现

    总结

    通过阅读《Redis设计与实现》前两章,对Redis的底层实现有了初步的了解。后续会继续研究Redis两种持久化方式和线程架构方面。


    参考来源:
    1. 《Redis设计与实现》
    2. 《Redis实战》
    3. http://www.cnblogs.com/jaycekon/p/6227442.html
    4. https://blog.csdn.net/u011531613/article/details/70193720?locationNum=7&fps=1
    5. https://blog.csdn.net/wcf373722432/article/details/78678504
    6. https://www.cnblogs.com/ysocean/p/9080942.html

    展开全文
  • oracle基础应用

    2018-06-04 00:40:00
    --先来一波介绍: oracle是一款关系数据库,具有以下特点: 1.支持多用户,大事务量事务...如果把数据库理解为硬盘文件,则数据库实例就是通过内存分享运行状态一组服务器的后台进程。 表空间:每个orac...

    --先来一波介绍:

    oracle是一款关系型数据库,具有以下特点:

    1.支持多用户,大事务量的事务处理

    2.在保持数据安全和数据完整性方面性能优越

    3.支持分布式数据处理

    4.具有可移植性

    数据库实例:每个启动的数据库都对应一个数据库实例,由这个实例来访问数据库中的数据。如果把数据库理解为硬盘上的文件,则数据库实例就是通过内存分享运行状态的一组服务器的后台进程。

    表空间:每个oracle数据库由若干个表空间组成,用户在数据库中建立的所有内容都被存储在表空间内.一个表空间由多个数据文件组成,但一个数据文件只属于一个表空间.属于数据库的逻辑结构.

     

    安装:自行百度(我用的时11g)

    window下启动数据库(开启服务):1.OracleServiceSID时Oracle数据库服务,默认自启,否则客户端连接数据库会报错。

                                                      2.OracleOraDb11g_home1TNSListenter,监听服务,监听来自客户端连接的请求(本地连接可不启,使用自带的sqlplus连接。但若是第三方客户端连接,必须开启)

                                                       3.OracleDBConsoleSID:数据库控制台服务

    服务器端和客户端的配置可通过相应的配置文件查看:   LISTENER.ora    TNSNAME.ora

     

    --oracle常用的数据类型:

    1.字符串数据类型

    char:固定长度的字符串,默认占用1字节

    varchar2:可变长度的字符串

    nchar :用来存储Unicode字符集类型,双字节

    nvarchar2 :存储国际化可变长度的字符串

     

    2.数值数据类型:

    number:可以存储证书,负数,零,定点数,精度为38位的浮点数

    格式:number(p,s)

    p:有效位数,冲左边第一个不为0的数算起,小数点和位数不计入位数。

    s:小数点右边数字的位数

    使用规则:先精确到小数点s位,若有效位数《=p,则正确。

     

    3.日期时间数据类型

    date:日期和时间的数据

    timestamp:用于存储日期的年月日和时间的时分秒

    (若数据库内的日期和我们查询出来的不一样,可能系统环境变量没有设置)

     

    4.lob数据类型

    clob:存储大量字符数据,大量文字内容的文档

    blob:二进制对象,音频视频等

    nclob:存储大的nchar字符数据,不大于4gb

     

    --伪列,只提供显示操作,不能插入,更新,删除它们的值。

    rowid : 不管数据是否重复,每条数据对应的rowid全局唯一

    rownum : 主要用于分页,返回一个数值代表行的次序

    例如:查询emp表第五条至第10条的记录

    --先内层查询使用中止行筛选出结果集,然后在外层查询从结果集找出符合的
    select rn,em.empno,em.ename from ( select rownum rn,emp.* from emp where rownum<=10) em where rn>=5;

      

     

    --sql语言介绍

    1.数据定义语言(DDL) : create   alter truncate  drop

     

    2.数据操纵语言(DML) : insert  select   update  delete

    --distinct子句筛选结果集中内容全部相同的行,仅保留一行。

       列别名:若别名中包含特殊字符(如空格),则使用双引号括起来.

        使用现有表创建新表:

        --表和数据的完全复制

         create table newStuInfo

         as

         select * from stuInfo;

         --仅要表的结构

         ....where 1<>2;

     

    3.事务控制语言(TCL) : commit   savepoint  rollback

        --合适开启事务

           在oracle中,事务在上一次事务结束后,在下一次修改时自动开启

       --合适结束事务

           1)数据被提交

             发出commit    /    执行DDL或DCL语句,事务自动提交      /       与oracle分离,如退出第三方客户端

            2)数据被撤销

              发出rollback指令       /      服务器进程异常结束        /     dba停止会话

     

    4.事务控制语言(DCL) grant  revoke

     

     

    --sql操作符

           -集合操作符: 将两个查询的结果组合成一个结果集

           union : 两个查询选定的所有不重复的行

            union all  : 就算重复我们也要,all

            intersect  : 返回两个查询都有的行,即两表相同的数据

            minus  : 只返回第一个查询选定,二未被第二个查询选定

     

            -连接操作符(||):  用于将两个或多个字符串合并成一个字符串,或将一个字符串与一个数值合并在一起

     

    --sql函数

           to_char():转换位字符串类型

           to_date():转换位日期类型

            to_number():转换为数值类型

     

     

    oracle数据库应用:

     

    --表空间:数据库逻辑结构的一个重要组件。表空间可以存放各种应用对象,如表,索引。每个表空间由一个或多个数据文件组成.

     使用表空间的目的:对不同的用户分配不同的表空间,对不同的模式对象分配不同的表空间,方便对用户数据的操作,对模式对象的管理。

    可以将不同的数据文件创建到不同的磁盘,有利于管理磁盘空间,有利于提高io性能。

    语法:       创建表空间:

           create tablespace tablespacename

           datafile 'filename'   size [k/m]  autoextend [off/on]

          --off:不扩容      on:空间用完自动扩容

    表空间扩容:     1.alter database  datafile 'filename'   resize  [k/m];

                             2.添加数据文件: alter tablespace tablespacename  add   datafile 'filename'

                                                        size  [k/m]   autoextend  [off/on];

    删除表空间: delete tablespace tablespacename including contents;

    表空间只读: alter tablespace  tablespacename readonly;

     

     

    --用户自定义管理:

    语法: 创建用户:create user user

                            identified  by   password

                            default   tablespace tablespacename

                            temporary      tablespace  tablespacename;

     

    --数据库权限管理:

    系统权限是指授权用户是否可以连接到数据库上及在数据库上可以进行哪些操作。

    对象权限是指用户对数据库中的对象所拥有的权限.

     

    用户可通过        被管理员授权        或          获取被管理元授权的角色

    oracle中系统预定义角色   :   connect:需要连接到数据库上的角色

                                                  resource :  创建表,触发器等

                                                  dba : 最高权限

     

    授权:      grant  权限/角色    to   用户;

                   revoke   权限/角色    from   用户;

     

    --序列

      序列(sequence) : 用来生成唯一,连续的证书的数据库对象,通常用来生成主键或唯一的值。

    创建序列语法:    create  sequence  sequence_name

                               start  with integer  //要生成的第一个序列号

                              increment  by integer   //增量

                              maxvalue  integer    // 最大

                              minvalue   integer  //最小

                              cycle // 到达最大值或最小值后,将继续开始从头开始生成值          nocycle   //默认的选项,当到达最大值或最小值后,将不在继续生成值

                               cache integer   //预先分配一组序列号,保存在内存中.      nocache                               //若忽略这俩,默认缓存20个序列号

    nextval  :  第一次获取序列的初始值,再次引用,增加序列值,返回新值

    currval   :  序列当前值

     

    更改序列: 使用alter sequence 

    删除序列: drop sequence  sequence_name

     

    --同义词  : 现有对象的别名

    当前用户创建私有同义词需要权限:create synnoym                     其它用户模式:create  synnoym

    创建私有同义词:        create  synonym  synonym_name     for   object_name;

     

    创建公有同义词需要权限  :  create  public  synnoym

         create  public  synnoym  synnoym_name   for  object_name;

    删除同义词:     drop  (public )       synnoym  synnoym_name;

     

     

    --索引  :   加快对表执行sql的速度.

    b树索引:建在重复值少的列,有助于按关键字的升序和降序扫描索引。

    create index index_name  on   table_name  (column_list);

     

    反向键索引:  对于连续增长的索引列,反向索引可以将索引数据分散在多个索引块,减少i/o瓶颈的发生。

    create index index_name_reverse on table(column)   reverse;

    位图索引: 最适合数据仓库和决策支持系统

                   优点: 大批及时查询,减少响应时间

                             占用空间明显减少
                              配置要求不高

    create bitmap index index_bit_name    on  table(column);

     

    删除索引:drop index index_name

    何时删除:不需要,损坏,批量加载前,加载后重建

    重建索引: alter index...rebuild

    何时重建:用户表一道新的表空间,应将索引一道指定的表空间

                      包含许多已经删除的项,

     

     

     

    --分区表:   一个表分为几个部分,存储在不同的位置。

    范围分区:以列的值的范围作为分区的划分条件,将不同的数据放入不同的分区

                   create table  分区表名   partition by range (column_name)(

                    partition 分区名  values  less than (分区条件),

                       ...

                    ) as select * from 原表明;

     

    间隔分区:范围分区的自动化,随着数据的增加自动划分更多的分区.

                     create table 分区表明(

                     列..

                      )

                      partition  by range (列)

                      interval  (NUMTOYMINTERVAL(n,'interval_unit'))     //按照括号内定义的间隔分区   (3,'month'):每三个月一分

                      (partition  分区名  values  less than  (分区条件);//不在该区,新建分区

         或者(另一种方式)创建间隔分区的结构和创建范围分区的结构差不多

    修改分区表:alter  table  分区表  add  partition 分区表 values less  than (column);

    查看几个分区,分区名称:  select * from user_tab_partitions;

     

     

    搞完,虽然只是些语法,但都是我自己敲的,不喜别喷。

    呃呃呃,貌似也没人看,就当自言自语了。哈哈

     

    转载于:https://www.cnblogs.com/lslshuo/p/9131468.html

    展开全文
  • Oracle

    千次阅读 2017-10-25 19:14:21
    Oracle 服务器:是一个关系数据库管理系统(RDBMS),它提供全面, 近乎完整信息管理。由Oracle 实例Oracle 数据库组成 Oracle 数据库: 位于硬盘上实际存放数据文件, 这些文件组织在一起, 成为一个整体, ...
  • NAS网络存储服务器是一款特殊设计文件存储和备份的服务器,它能够将网络中数据资料合理有效、安全地管理起来,并且可以作为备份设备将数据库和其它应用数据时时自动备份到NAS上。 三 为什么要选择基于NAS存储...
  • 第3部分为SQL Server 2008基本操作篇,介绍如何管理配置SQL Server 2008服务器、如何创建数据库和数据表、如何对数据库里数据进行操作;第4部分为数据库管理篇,介绍如何使用T-SQL程序对数据进行复杂运算,...
  • MongoDB详解

    2018-12-04 19:06:52
    介于关系数据库和关系数据库之间产品 –一款基于分布式文件存储数据库,旨在为WEB应用提供可扩展高性能数据存储解决方案 – 将数据存储为一个文档(类似JSON对象),数据结构有键值(key=value)对组成,...
  • 根据硬盘在断电时是否有足够电量保存内存,这可能是安全,也可能是不安全。 阅读表现 我们列出了正向反向顺序读取性能,以及随机查找性能。请注意,基准测试创建的数据库很小。因此,当工作集适合内存时...
  • Redis是一个速度极快关系数据库(NoSQL),他可以存储key5种不同类型value之间映射。能够将内存中键值数据持久化到硬盘当中。 redis集中常用存储比较 我们知道了Redis是基于内存的数据库,那么当...
  • 图书管理系统毕业设计+源码-java

    千次下载 热门讨论 2012-05-06 13:45:09
    ADO对象内核包含Connection(连接)、Command(命令)和Recordset(记录集)对象,利用它们,可以连接到数据库和检索记录集。ADO还提供DataSource组件,该组件将Conntect,Command和Recordset对象功能组合到一起。...
  • 事务处理原理 第2版

    热门讨论 2012-12-30 10:49:38
    3.7 数据库服务器与事务中间件 3.8 小结 第4章 队列化事务处理 4.1 为什么使用队列 4.2 队列事务处理模型 4.2.1 从服务器角度看排队 4.2.2 从客户端角度看排队 4.3 客户端恢复 4.4 处理不可撤消操作 4.5 ...
  • 4.13 数据库和其他文件转换 384 实例217 将硬盘文件目录转为数据库数据 384 实例218 将数据库文件转换为文本文件 386 实例219 将数据库数据传给Excel 388 实例220 将Excel数据传给Access数据库 389 实例221 ...
  • 4.13 数据库和其他文件转换 384 实例217 将硬盘文件目录转为数据库数据 384 实例218 将数据库文件转换为文本文件 386 实例219 将数据库数据传给Excel 388 实例220 将Excel数据传给Access数据库 389 实例221 ...
  • 20、索引对象 index

    2020-12-11 15:11:07
    关系数据库中,用户查找数据物理位置无关。为了能找到数据,表中每一行均...将索引对应表分别放在不同硬盘的不同表空间可以提高查询速度,因为oracle 能够并行读取不同硬盘的数据,这样查询可以避免产生i/o冲突
  • Hadoop课程-01

    2016-07-16 18:39:00
    2、熟练地在Hadoop操作系统以及关系数据库之间传递数据. 3、能独立指定数据集成方案 4、 Google低成本之道 不使用超级计算机,不使用存储(淘宝去i,去e,去o之路) 大量使用普通PC服务器(去掉机箱、...
  • SQL Server 2005基础教程--详细书签版

    热门讨论 2013-02-06 11:22:15
    前半部分以建立一个金融数据库系统为主线,从最基础的收集信息入手,一步步地引导读者学会如何保证数据库的安全,创建表、主键、索引等项目,在表之间建立恰当的关系,并掌握如何备份还原数据库;之后以前面建立的...
  • 学生学籍管理信息系统

    热门讨论 2009-05-28 14:51:27
    硬件需求:10M以上的LAN接入网络带宽,P4 3.0G Xeon CPU /1G内存/360G(10K) SCSI硬盘的服务器,P3以上微机(带网卡)的客户机,P4 3.0G Xeon CPU /1G内存/36G(10K) RAID硬盘的数据库服务器 本系统采用vb实现,依靠其...
  • 数据交换需求规格说明书

    热门讨论 2011-03-01 14:57:51
    根据客户需求数据交换平台主要采用数据中心数据交换代理节点结构来简化电子政务应用主体内部功能体之间、主体主体之间所存在复杂相互关系,在代理节点上提供相应服务来方便老应用系统接入并提供一致...
  •  0031 系统连接设备不能正常运转。  0032 其他进程正使用该文件,因此现在无法访问。  0033 另一进程已锁定该文件某一部分,因此现在无法访问。  0034 驱动器中软盘不正确。请将 %2 (卷标序列号:...
  • ORACLE数据库系统是美国ORACLE公司(甲骨文)提供以分布式数据库为核心一组软件产品,是目前最流行客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一。  拉里•埃里森  就业前景 从就业择业...
  • 呼叫中心通过智能呼叫分配、计算机电话集成、自动应答系统等高效的手段及人工座席,为客户提供迅速、准确的咨询信息以及业务受理投诉等服务,最大限度地提高客户的满意度,同时自然也使企业客户的关系更加紧密,...
  • Java EE常用框架.xmind

    2020-06-19 16:08:35
    全文搜索引擎是在硬盘搜索,比传统Mysql数据库是要快 比传统SQL多功能:查询结果有相关排名,可以有高亮显示 存储数据地方我们称之为索引库 原始记录表 分词表(倒排序表) 使用 将...
  • 实现从采购原材料开始,制成中间产品以及最终产品,最后由销售网络把产品送到消费者手中全过程物流集成控制,并随时跟踪回访您广大客户群,实现您客户建立紧密合作关系。 秘奥软件帮助企业把客户、零售...
  • 而公司用的服务器却不需要显示器显卡,网吧电脑可能不需要硬盘等。正因为这样设计,ET框架可以将所有的服务器组件都挂在一个服务器进程上,那么这个服务器进程就有了所有服务器的功能,一个进程就可以作为整组...
  • jsp九大内置对象

    2011-10-21 23:25:22
    同时分配一个String类型ID号,JSP引擎同时将这换个ID号发送到客户端,存放在Cookie中,这样Session对象,直到客户关闭浏览器后,服务器端该客户Session对象才取消,并且客户会话对应关系消失。当客户重新...

空空如也

空空如也

1 2
收藏数 40
精华内容 16
关键字:

服务器与数据库和硬盘的关系