REDIS

NoSQL = Not Only SQL.
高并发读写 会导致关系型数据库压力过大


NOSQL分类

NOSQL优点:数据之间无关系, 易拓展, 灵活的数据模型, 大数据量,高性能, 高可用。

redis: 高性能键值对数据库


支持的数据结构
redis应用场景
jedis连接步骤

Jedis配置

  1. 写JedisConfig 配置连接数 账号密码 连接时间 地址 等等
  2. 写service 要进行哪些操作(其中需要的一些获得jedis的对象配置在@configuration中 比如jedispool什么的)
  3. 封装Prefix(prefix, expires) 使得 key不冲突,按模块区分
image.png

字符串常用操作:

  1. 当做整形用: incr 、 incrby、del...
  2. 当做字符串: set、 append…

哈希表常用操作:

  1. hset 表名 key value(存值) hmset 表名 key1 value1 key2 value2...(多)
  2. hget 表名 key(取值) hmget 表名 key1 key2...(多)
  3. del 表名(删除整个集合) hdel 表名 key删除这个key value
  4. hincrby 表名 key number(要增加的值) 给key里的value+number

列表常用操作:

  1. lpush/rpush 表名 value1,value2,value3...
  2. lrange 表名 from to ->[from, to]里的元素 从0开始并且包括尾索引
  3. lpop/rpop 表名
  4. llen 表名
  5. 常用于消息队列, 多个程序之间的通信。 生产者:一个程序往list中添加元素。 消费者:一个程序往list中取走元素。为防止消费者取走后没有正常消费(出现了一些异常等等), 通常需要使用poppush操作,在取走的同时放进一个备份队列,当确定无误后,再将备份队列中的数据删除。


    消息通信

集合(set) 常用命令:

  1. sadd 表名 value1, value2 ...
  2. srem 表名 value1, value2 ...
  3. smembers 表名(获得全集)
  4. sismember 表名 value(判断value在不在s中)
  5. 集合运算 union、diff、inter...
  6. scard 表名 (获得该表的长度)

有序集合(sorted-set)常用命令:
实质上是一个类似TreeMap的东西,等价于TreeMap(value,score)且按score排序

  1. zadd 表名 score1 value1 score2 value2 score3 value3
  2. zscore 表名 value(获得该value的分数 )
  3. zcard 表名(获得该表的长度)

redis的特性
多数据库, 类似MYSQL的不同数据库, REDIS有0-15(共16个数据库),通过SELECT切换。
支持事务, multi exec discard.

redis持久化
RDB:每过一段时间将数据写入硬盘
AOF:一般用来记录日志,修改后就同步
无持久化

  • 单节点redis和redis cluster不同点:
    • jediscluster不支持ping操作
    • jediscluster不能同时操作多个key(mset、mget)
    • jediscluster不支持flushall、flushdb操作

单线程的Redis为什么这么快?

  • 纯内存操作
  • 单线程操作, 避免了频繁的上下文切换
  • 采用了非阻塞I/O多路复用机制
    • 传统并发模型: 每个I/O流都有一个新的线程管理
    • I/O多路复用: 单个线程, 通过跟踪每个I/O流的状态,管理多个I/O流

REDIS的过期策略以及内存淘汰机制:定期删除+惰性删除策略

  • 定时删除(消耗资源大,到时间就一定要删除,可能此时正有请求),定期随机检查部分KEY并进行删除
  • 定期删除如果没有删除到,就会执行惰性删除(在获取某个Key的时候,Redis会检查这个Key是否设置了过期时间,如果过期了,此时就会删除)
  • 如果即没定期淘汰,也没访问,那么会导致内存越来越高。就应该采用内存淘汰机制(ALLKEYS-LRU 键空间中,移除最近最少使用的KEY)。

四个常见问题:

  • 缓存和数据库双写一致性问题

    • ...
  • 缓存雪崩问题

    • 原因:缓存同一时间大面积失效,请求又都怼到了数据库上。
    • 解决方案:给缓存失效时间加个随机值, 互斥锁, 双缓存(?)
  • 缓存击穿问题

    • 原因:所有请求避开缓存,导致所有请求怼数据库
    • 解决:利用互斥锁(获得锁才能请求数据库), 异步更新机制(维护一个缓存失效时间,如果缓存过期了,异步起一个线程去读数据库,更新缓存),提供一个能迅速判断请求是否有效的拦截机制(?如果Key不合法,直接返回)
  • 缓存的并发竞争问题

    • 多个子系统Set 一个Key(如果不要求按顺序对Key操作, 使用分布式锁, 抢到锁就可以set)、(要求顺序,可以在VALUE上加上时间戳, 根据时间戳来进行时间操作)。
  • 一些常见操作

    • setnx(SET if Not eXist)
    • setex(set and expire) 设置值并且将key的生存时间设为seconds。
    • hdel(删除哈希表中的一个或多个指定域,不存在的域将被忽略) HDEL KEY field[field ...]
    • hmset (hash multi set)
    • hscan(hash iterator) hscan(key, cursor, match), cursor用于指定游标, match用于过滤结果。【cursor从0开始, 当cursor为0时结束。】
    • zrem(删除多个)。
  • jediscluster使用crc16哈希槽算法

  • 分布式session

    1. 考虑到使用集群来跑项目 , session难以共享。
    2. 使用redis模拟session。 cookie保存一个token, 然后通过这个token来确定一个用户在redis中的数据。(其中涉及到json序列化和反序列化)
  • jediscluster API 基本与 cmd client一致, 用个service或者util简单封装一下就好。

  • jedis和redistemplate:http://shift-alt-ctrl.iteye.com/blog/1886831

  • spring redistemplate

    • 内部操作的是jedis
    • redisTemplate.opsForValue();//操作字符串
    • redisTemplate.opsForHash();//操作hash
    • redisTemplate.opsForList();//操作list
    • redisTemplate.opsForSet();//操作set
    • redisTemplate.opsForZSet();//操作有序set
    • 通过4个序列化方法定义序列化方式(貌似不使用默认也不指定,是通过byte传输), 其它使用参考API。
  • redis分布式锁:

    1. 竞争资源抢占一个锁(一个String表示某个特定资源), 锁的有效时间(锁持续的时间),超时时间(获取锁失败后重试的时间)
    2. 加锁逻辑
    3. setnx, 如果成功则成功,否则
    4. get 判断锁是否超时, 超时的情况下 getset并且判断getset得到的值是否和之前一致(CAS的思想),如果是的话返回true,否则
    5. 不断尝试获得锁
    6. 解锁逻辑
    7. 如果当前时间 > 锁的到期时间 , 不做处理
    8. 否则删除key
  • redis pipeline:

    • redis 是一个基于TCP 的C/S 架构软件, 当客户端向服务端发送请求时, 需要消耗一定的时间用于往返传输数据。如果客户端需要服务端进行100次操作, 显然逐条发送会造成redis 空闲(处理速度大于操作到来的速度) 而 资源浪费。
    • 第一种方式是通过batch, 单条批量操作, multiset、multiget这样。
    • 第二种方式是通过pipeline, 思路一样, 只不过用在set上, 没法multi多个set,而pipeline是把指令作为流水线打过去。
  • redis lua:

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

推荐阅读更多精彩内容

  • Nosql概述 在介绍Redis之前,首先先要介绍Nosql的概念。 互联网架构发展 在90年代的时候,计算机访问...
    COKIDCC阅读 689评论 0 1
  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 3,981评论 2 27
  • 1、NoSQL 什么是NoSQLNo Only SQL非关系型的数据库 为什么需要NoSQLHigh perfor...
    Hey_Shaw阅读 396评论 0 1
  • 昨天下班后,经同事推荐,跑到单位附近一个汽修厂保养车子,据说保养费只有4S店一半,便宜又近,何乐而不为呢。 平时去...
    冷锋刀语阅读 684评论 0 0
  • 今日福利特价 资生堂男士洗面奶,58享包邮 日本百年品牌资生堂旗下的UNO吾诺男士洗面奶,针对不同肌肤对症下药,使...
    踏歌Ty阅读 115评论 0 0