Redis学习笔记

Redis简介

REmote DIctionary Server(Redis) 是一个由SalvatoreSanfilippo写的key-value存储系统。 Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 它通常被称为数据结构服务器,因为值(value)可以是字符串(String), 哈希(Map), 列表(list), 集合(sets) 和有序集合(sorted sets)等类型。

Redis五大基本数据类型


Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

String(字符串)

string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。

string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

常用命令:set、get、decr、incr、mget等。

注意:一个键最大能存储512MB。

Hash(哈希)

Redis hash 是一个键值(key=>value)对集合;是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

每个 hash 可以存储 232 -1 键值对(40多亿)。

常用命令:hget、hset、hgetall等。

应用场景:存储一些结构化的数据,比如用户的昵称、年龄、性别、积分等,存储一个用户信息对象数据。

List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

list类型经常会被用于消息队列的服务,以完成多程序之间的消息交换。

常用命令:lpush、rpush、lpop、rpop、lrange等。

列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。

Set(集合)

Redis的Set是string类型的无序集合。和列表一样,在执行插入和删除和判断是否存在某元素时,效率是很高的。集合最大的优势在于可以进行交集并集差集操作。Set可包含的最大元素数量是4294967295。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

zset(sorted set:有序集合)

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

sorted set是插入有序的,即自动排序。

常用命令:zadd、zrange、zrem、zcard等。

当你需要一个有序的并且不重复的集合列表时,那么可以选择sorted set数据结构。


Redis配置文件常用参数及其默认值

(1)daemonize no

Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

(2)pidfile /var/run/redis.pid

当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定

(3)port 6379

指定Redis监听端口,默认端口为6379

如果指定0端口,表示Redis不监听TCP连接

(4)bind 127.0.0.1

绑定的主机地址

可以绑定单一接口,如果没有绑定,所有接口都会监听到来的连接

(5)timeout 0

当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能

(6)loglevel verbose

指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose

(7)logfile stdout

日志记录方式,默认为标准输出,如果配置为redis为守护进程方式运行,而这里又配置为标准输出,则日志将会发送给/dev/null

(8)databases 16

设置数据库的数量,默认数据库为0,可以使用select <dbid>命令在连接上指定数据库id

dbid是从0到‘databases’-1的数目



Redis数据持久化


RDB:

Redis会创建(fork)单独的一个子进程来进行持久化操作,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。这个过程主进程不进行任何IO操作,这就确保了Redis的性能。

如果需要进行大规模的数据恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。

save与bgsave:

1.save触发方式

该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。

执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。我们的客户端可能都是几万或者是几十万,这种方式显然不可取。


2.bgsave触发方式

执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求.

具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。


RDB配置参数:

(1)

save 900 1

save 300 10

save 60 10000

指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合

表示 900秒(15分钟)内有1个更改

         300秒(5分钟)内有10个更改

         60秒内有10000个更改

满足三个条件中的任意一个,即将数据从内存同步到数据文件

(2)rdbcompression yes

指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大

(3)rdbchecksum yes

默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能

(4)stop-writes-on-bgsave-error yes

默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了

(5)dbfilename dump.rdb

指定本地数据库文件名,默认值为dump.rdb

(6)dir ./

工作目录.

指定本地数据库存放目录,文件名由上一个dbfilename配置项指定

这里只能指定一个目录,不能指定文件名


AOF:

全量备份总是耗时的,有时候我们提供一种更加高效的方式AOF,工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到文件中。

通俗的理解就是日志记录。

与hadoop的持久化操作类似,hadoop的数据持久化是通过对数据进行操作后,将操作日志写进edits文件,由secondarynamenode定时将edits文件与存储hadoop数据快照的fsimage文件进行合并,生成新的fsimage,这样既保证了数据的持久性又不会影响namenode的性能。

redis也是类似,通过fork出一个子进程,将redis的操作日志写进appendonly.aof文件中,以保证即使服务器宕机也能通过appendonly.aof对rdb文件进行恢复。


AOF三种触发机制

(1)每修改同步always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好

(2)每秒同步everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失

(3)不同no:从不同步


AOF配置参数:


(1)appendonly no

指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。

因为redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no

(2)appendfsync everysec

指定更新日志条件,共有3个可选值:

1.no:表示等操作系统进行数据缓存同步到磁盘(快)

2. always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)

3.everysec:表示每秒同步一次(折衷,默认值)

(3)appendfilename appendonly.aof

指定更新日志文件名,默认为appendonly.aof

(4)no-appendfsync-on-rewrite

是否在后台写时同步单写,默认值no(表示需要同步).这里的后台写,表示后台正在重写文件.no表示新的主进程的set操作会被阻塞掉,而yes表示新的主进程的set不会被阻塞,待整个后台写完成之后再将这部分set操作同步到aof文件中。但这可能会存在数据丢失的风险(机率很小),如果对性能有要求,可以设置为yes,仅在后台写时会异步处理命令.

(5)auto-aof-rewrite-percentage aof

文件增长比例,指当前aof文件比上次重写的增长比例大小。aof重写即在aof文件在一定大小之后,重新将整个内存写到aof文件当中,以反映最新的状态(相当于bgsave)。这样就避免了,aof文件过大而实际内存数据小的问题(频繁修改数据问题).

(6)auto-aof-rewrite-min-size aof

文件重写最小的文件大小,即最开始aof文件必须要达到这个文件时才触发,后面的每次重写就不会根据这个变量了(根据上一次重写完成之后的大小).此变量仅初始化启动redis有效.如果是redis恢复时,则lastSize等于初始aof文件大小.

(7)aof-load-truncated yes

指redis在恢复时,会忽略最后一条可能存在问题的指令。默认值yes。即在aof写入时,可能存在指令写错的问题(突然断电,写了一半),这种情况下,yes会log并继续,而no会直接恢复失败.


Redis 在Linux下基本操作

安装Redis或者下载Redis镜像,这里使用镜像方式

命令:Docker pull redis:3.0

添加本地redis配置文件夹

mkdir /opt/module/configs/redis-config

mkdir /opt/module/configs/redis-config/data

接着用镜像生成容器并配置容器卷

docker run -p 6379:6379 --name redis -v /opt/module/configs/redis-config/redis.conf:/etc/redis/redis.conf  -v /opt/module/configs/redis-config/data:/data -d redis:3.0 redis-server /etc/redis/redis.conf

需要注意的是如果以这种指定redis.conf配置文件方式开启redis,必须设置 daemonize no,否则redis会在容器中以守护进程的方式后台运行,docker会自动关闭该容器



Redis事务:

Redis事务相关命令:

MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。

EXEC:执行事务中的所有操作命令。

DISCARD:取消事务,放弃执行事务块中的所有命令。

WATCH:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。

UNWATCH:取消WATCH对所有key的监视。

但是redis的事务不知支持回滚,事务更像是一个任务队列,彼此之间的成功与否互不影响。

严格的说Redis的命令是原子性的,而事务是非原子性的,我们要让Redis事务完全具有事务回滚的能力,需要借助于命令WATCH来实现。

Redis使用WATCH命令来决定事务是继续执行还是回滚,那就需要在MULTI之前使用WATCH来监控某些键值对,然后使用MULTI命令来开启事务,执行对数据结构操作的各种命令,此时这些命令入队列。

当使用EXEC执行事务时,首先会比对WATCH所监控的键值对,如果没发生改变,它会执行事务队列中的命令,提交事务;如果发生变化,将不会执行事务中的任何命令,同时事务回滚。当然无论是否回滚,Redis都会取消执行事务前的WATCH命令。



SpringBoot整合Redis


添加依赖


配置文件


注入redisTemplate

接着就可以使用redis了。

RedisTemplate提供了对应的ops操作五大Redis数据类型API,可以实现对应五种数据类型的基本操作。

但无论是哪种数据类型的操作,数据存入Redis数据库里后都是以Bytes数组的方式,Map的KV都是如此。如果我们用对应类型的反序列化器对数据进行操作那么并不会影响使用,但是如果我们需要在Redis里来直接对数据进行操作,那么我们将看到的都会是无可读性的Bytes数组。

这是因为RedisTemplate默认使用的是JDK自带的JdkSerializationRedisSerializer,还需要被序列化的类实现Serializer接口。

Spring也提供了StringRedisTemplate为我们实现String类型的序列化操作,通过该Template,字符串类型的数据会以可视化字符串的形式存储在Redis中,但是只能存储String类型。


点开它的实现,发现它也只是继承并修改了了RedisTemplate的序列化器。

SpringBoot为我们注入了RedisTemplate,我们也可以选择通过自定义RedisConfig @Bean的方式重写RedisTemplate的注入,来修改例如序列化与反序列化器的配置。


仅仅是这样我们就实现了类似StringRedisTemplate的自定义RedisTemplate。

也可以设置JSON格式的序列化方式



1,用StringRedisSerializer进行序列化的值,在Java和Redis中保存的内容是一样的

2,用Jackson2JsonRedisSerializer进行序列化的值,在Redis中保存的内容,比Java中多了一对双引号。

3,用JdkSerializationRedisSerializer进行序列化的值,对于Key-Value的Value来说,是在Redis中是不可读的。


事务:

在spring中要使用Redis注解式事务,首先要设置RedisTemplate的enableTransactionSupport属性为true,然后配置一个jdbc的事务管理器。

这里有一点非常重要,一旦这样配置,所有使用这个template的redis操作都必须走注解式事务,要不然会导致连接一直占用,不关闭。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言...
    白穹雨阅读 579评论 0 1
  • 最近学习了一段时间的redis,以下是笔记,欢迎各位大佬们留言评论,若有不对的地方请指出,我会及时更正!蟹蟹大家!...
    吃板栗的猫阅读 899评论 1 2
  • linux下载: 去redis官网,复制下载链接 cd 一个下载目录,然后 sudo wget http://.....
    月明星稀_8184阅读 166评论 0 0
  • 此文章只是用来做笔记,期间拖了很久,多多见谅。 一.Redis简介 我们一说到redis就会想到kv键值对,C...
    yzn2015阅读 271评论 0 0
  • 夜莺2517阅读 127,708评论 1 9