Redis大全手册(上)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis大全手册

著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

API的理解和使用

通用命令

keys
dbsize #计算key的总数
exists key  #检查key是否存在
del key [key]   #删除指定key-value
type key    #返回key的类型
expire key seconds      #key在seconds过期
ttl key     #查看key剩余的过期时间
persist key     #去掉key的过期时间
127.0.0.1:6379> set hello world OK
127.0.0.1:6379> expire hello 20(integer)1
127.0.0.1:6379> ttl hello(integer)17
127.0.0.1:6379> get hello"world"
127.0.0.1:6379> ttl hello(integer)12
127.0.0.1:6379> ttl hello(integer)-2
127.0.0.1:6379> get hello(nil)
127.0.0.1:6379>

-2表示过期

127.0.0.1:6379> set hello world OK
127.0.0.1:6379> expire hello 20(integer)1
127.0.0.1:6379> ttl hello(integer)18
127.0.0.1:6379> persist hello(integer)1
127.0.0.1:6379> ttl hello(integer)-1
127.0.0.1:6379> get hello"world"
127.0.0.1:6379>

-1代表key存在,并且没有过期时间

kyes基本不在生产环境使用

keys *    #遍历所有key
key [pattern]
命令 时间复杂度
keys O(n)
dbsize O(1)
del O(1)
exists O(1)
expire O(1)
type O(1)

数据结构和内部编码

89db8be1b9cf7c33d3f807744212ff9.png

redis为什么这么快?

  1. 纯内存
  2. 非阻塞IO
  3. 避免线程切换和竞态消耗

单线程需要注意什么?

  1. 一次只运行一条命令
  2. 拒绝长(慢)命令
keys, flushall, flushdb, slow lua script, mutil/exec, operate big value(collention)
  1. 其实不是单线程
fysnc file descriptor
close file descriptor

字符串

get key     #获取key对应的value O(1)
set key value   #设置key-value  O(1)
del key     #删除key-value  O(1)
mset key value key value    #批量设置key-value   O(n)
mget key key   #批量获取key-value    O(n)
incr key    #key自增1,如果key不存在,自增后get(key)=1   O(1)
decr key    #key自减1,如果key不存在,自减后get(key)=-1   O(1)
incrby key k    #key自增k,如果key不存在,自增后get(key)=k   O(1)
decrby key k    #key自减k,如果key不存在,自减后get(key)=-k   O(1)
set key value   #不管key是否存在,都设置   O(1)
setnx key value  #key不存在,才设置     O(1)
set key value xx    #key存在,才设置     O(1)
getset key newvalue     #set key newvalue并返回旧的value
append key value    #将value追加到旧的value
strlen key  #返回字符串的长度(注意中文)
incrbyfloat key 3.5   #增加key对应的值3.5
getrange key start end   #获取字符串指定下标的所有的值
setrange key index value    #设置下标所有对应的值


96066f2c85beddd0a452c3520b15a35.png4ba7b0b9b425e4d9c597c0658db478b.png

hash

哈希键值结构

7e9c47da7309f35d404ec3fb625b7e0.png

hmset key field value field value   #批量设置   O(n)
hmget key field field   #批量获取       O(n)
hget key field   #获取hash key对应的field的value    O(1)
hset key field value    #设置hash key对应field的value   O(1)
hdel key field  #删除hash key对应的field的value     O(1)
hexists key field   #判断hash key 是否有field   O(1)
hlen key    #获取hash key field的数量       O(1)
hgetall key     #h返回hash key对应所有的field和value    O(n)
hvals key   #返回hash key对应所有field的value   O(n)
hkeys key   #返回hash key对应所有field      O(n)
hsetnx key field value  #设置hash key对应field的value(如field存在,则失败)    O(1)
hincrby key field intCounter    #hash key 对应的field的value自增intCounter  O(1)
hincrbyfloat key field floatCounter     #hincrby浮点数版    O(1)

记录网站每个用户个人主页的访问量

#redis实现
incr userid:pagevies(单线程,无竞争)
hincrby user:1:info pageview count
#java模拟代码
public VideoInfo get(long id){
    String redisKey = redisPrefix + id;
    Map<String,String> hashMap = redis.hgetAll(redisKey);
    VideoInfo videoInfo = transferMapToVideo(hashMap);
    if(videoInfo == null){
        videoInfo = mysql.get(id);
        if(videoInfo != null){
            redis.hmset(redisKey, transferMapToVideo(videoInfo))
        }
    }
    return videoInfo;
}

小心使用hgetall(redis单线程)例子:如保存一个用户的信息的实现,下面说3种情形,当然还有更多种其他方式

  • String v1
  • 55c2f45d51995154f8124ac5b349ad7.png
  • String v2
  • 7eda083f02517218e795930e49b064f.png
  • hash
  • 853b9f5218e680cf3d2cccca2f78e11.png
  • 比较
命令 优点 缺点
string v1 编程简单,可能节约内存 1. 序列号开销
2. 设置属性要操作整个数据
string v2 直观,可以部分更新 1. 内存占用较大
2. key较为分散
hash 直观、节省空间、可以部分更新 1. 编程稍微复杂
2. ttl不好控制

list

特点:有序、可以重复、左右两边插入弹出

rpush key value value ...valueN     #从列表右端插入值(1-N个)
lpush key value value ...valueN     #从列表左端插入值(1-N个)
linsert key before|after value newValue     #在list指定的前|后插入newValue
lpop key    #从列表左侧弹出一个item
rpop key    #从列表右侧弹出一个item
#根据count值,从列表中删除所有value相等的项
#count > 0,从左到右,删除最多count个value相等的项
#count < 0,从右到左,删除最多Math.abs(count)个value相等的项
#count = 0,删除所有value相等的项
lrem key count value
ltrim key start end     #按照索引范围修剪列表      O(n)
lrange key start end    #获取列表指定索引范围所有item   O(n)
llen key    #获取列表长度   O(1)
lset key index newValue     #设置列表指定索引值为newValue   O(n)
blpop key timeout   #lpop阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞     O(1)
brpop key timeout   #rpop阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞     O(1)
##小建议-数据结构类比
lpush + lpop = stack
lpush + rpop = queue
lpush + ltrim = capped collection
lpush + brpop = message quere

慢查询

2a142bd3dfa3902d1725238777fb380.png

56044eb6249c12daf631044b24442b9.png

  • slowlog-max-len
  1. 先进先出队列
  2. 固定长度
  3. 保存在内存中

慢查询命令

slowlog get [n]     #获取慢查询队列
slowlog len     #获取慢查询队列长度
slowlog reset   #清空慢查询队列
  • 慢查询阀值(单位:微妙)
  • slowlog-log-slower-than=0   记录所有命令
  • slowlog-log-slower=than<0   不记录任何命令配置方式
1. 默认值
config get slowlog-max-len = 128
config get slowlog-log-slower-than = 1000
2. 修改配置文件重启
3. 动态配置
config set slowlog-max-len 1000
config set slowlog-log-slower-than 1000

运维经验

  1. slowlog-max-len不要设置过大,默认10ms,通常设置1ms
  2. slowlog-log-slower-than不要设置过小,通常设置1000左右
  3. 理解命令生命周期
  4. 定期持久化慢查询

pipeline

批量网络命令通信模型

4b2a416e5e525a8691c0b8f8a5995e4.png

什么是流水线

a7b533ae228b1bc64360beff7bd16a5.png

流水线作用

命令 N个命令操作 1次pipeline(n个命令)
时间 n次网络 + n次命令 1次网络 + n次命令
数据量 1条命令 n条命令
  • redis的命令时间是微秒级别
  • pipeline每次条数要控制(网络原因)

a5013ce1a31e736c13ce0b1db13c55e.png

从上图举例,redis命令的执行时间是很快的,但是由于数据需要通过网络传输,由于2个地区相隔很远,数据以光速度传播也需要时间,然而这个时间有可能比redis执行时间要长。

pipeline-Jedis实现

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
    <type>jar</type>
</dependency>
#没用pipeline, 1W次hset需要50s
Jedis jedis = new Jedis("127.0.0.1", 6379);
for(int i=0;i<10000;i++){
    jedis.hset("hashkey:"+i,"field"+i, "value"+i);
}
#使用pipeline
Jedis jedis = new Jedis("127.0.0.1", 6379);
for(int i=0;i<100;i++){
    Pipeline pipeline = jedis.pipelined();
    for(int j=i*100; j<(i+1)*100;j++){
        pipeline.hset("hashkey:"+j,"field"+j, "value"+j);
    }
    pipeline.syncAndReturnAll();
}

使用建议

  1. 注意每次pipeline携带的数据量
  2. pipeline每次只能作用在一个Redis节点上
  3. M操作和pipeline的区别

发布订阅

角色发布者(publisher) 订阅者(subscriber) 频道(channel)模型

33e98b428b6d28b343d1cfd0fe70ed9.png

publish channel message     #发布消息
subscribe [channel]     #一个或多个
unsubscribe [channel]     #一个或多个
psubscribe [pattern...]     #订阅模式
punsubscribe [pattern...]   #退订指定的模式
pubsub channels     #列出至少有一个订阅者的频道
pubsub numsub [channel...]      #列出给定频道的订阅者数量
pubsub numpat    #列出被订阅模式的数量
127.0.0.1:6379> publish sou:tv "hello world"(integer)1
127.0.0.1:6379> publish sou:tv "hello world333"(integer)1
127.0.0.1:6379> 
127.0.0.1:6379> subscribe sou:tv
Reading messages... (press Ctrl-c to quit1) "subscribe"2)"sou:tv"
3)(integer)11)"message"2)"sou:tv"
3) "hello world"1)"message"2)'"sou:tv"
3) "hello world333" 

位图

b7cde13cd7b443ae72a408b98370a7b.png

127.0.0.1:6379> set hello big OK
127.0.0.1:6379> getbit hello 0(integer)0
127.0.0.1:6379> getbit hello 1(integer)1
127.0.0.1:6379> setbit hello 7 1(integer)0
127.0.0.1:6379> get hello“cig"
127.0.0.1:6379> 
setbit key offset value     #给位图指定索引设置值
getbit key offset       #获取位图指定索引的值
bitcount key [start end]    #获取位图指定范围(start到end,单位为字节,如果不指定就是获取全部)位值为1的个数
bitop key targetBit [start] [end]   #计算位图指定范围第一个偏移量对应的值等于targetBit的位置

独立用户统计

  1. 使用set和Bitmap两种方式
  2. 1亿用户,5千万独立
数据类型 每个userid占用空间 需要存储的用户量 全部存储量
set 32位(假设userid用的是整型,实际场景很多用长整型) 50000000 32位*50000000=190.7348633MB
Bitmap 1位 100000000 1位*100000000=11.920929MB
一天 一个月 一年
set 200M 6G 72G 大约值
Bitmap 12.5M 375M 4.5G 大约值

只有十万独立用户呢?

数据类型 每个userid占用空间 需要存储的用户量 全部存储量
set 32位(假设userid用的是整型,实际场景很多用长整型) 100000 32位*1000000=0.3814697MB
Bitmap 1位 100000 1位*100000000=0.0119209MB

使用建议

  1. type = string,最大512MB
  2. 注意setbit的偏移量,可能有较大耗时
  3. 位图不是绝对好

HyperLogLog

  1. 极小空间完成独立数量统计
  2. 本质还是字符串
  3. pfcount 统计有一定错误率0.81%
  4. 无法取出单条数据
pfadd key element [element...]      #向hyperloglog添加元素
pfcount key [key]       #计算hyperloglog的独立总数
pfmerge destkey sourcekey [sourcekey]   #合并多个hyperloglog
redis> pfadd 2017_03_06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4”(integer)1
redis> pfcount 2017_03_06:unique:ids(integer) 4
redis> pfadd 2017_03 06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-90'(integer) 1
redis> pfcount 2017_03 06:unique:ids
(integer)5  
redis> pfadd2016 03 06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"(integer) 1
redis> pfcount 2016 03_06:unique:ids(integer) 4
redis> pfadd 2016_03_05:unique:ids "uuid-4" "uuid-5" "uuid-6" "uuid-7"(integer)1
redis> pfcount 2016 03 05:unique:ids(integer)4
redis> pfmerge 2016_03_05_06:unique:ids 2016_03_05:unique:ids2016_03_06:unique:ids OK
redis> pfcount 2016_03_05_06:unique:ids
(integer) 7 

afdf25ce2a35eeacf7a2e9dbcf9499f.png

geo地理信息定位

  1. 3.2版本以后才有geo
  2. geoKey的类型是zset,type geoKey = zset
  3. 没有删除的API,可以使用zrem key member
geo key longitude latitude member [longitude latitude member...]    #增加地理位置信息
geopos key member [member...]       #获取地理位置信息
geodist key member1 member2 [unit]    #获取两个地理位置的距离,unit:m、km、mi、ft

更多命令参考

127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing(integer) 1
127.0.0.1:6379> geoadd cities:locations 117.12 39.08 tianjin114.29 38.02 shijiazhuang 118.01 39.38 tangshan 115.29 38.51 baoding
(inteaer)4  
127.0.0.1:6379> geopos cities:locations tianjin1) 1) "117.12000042200088501"
2) "39.0800000535766543"
127.0.0.1:6379> geodist cities:locations tianjin beijing km"89.2061"

Redis持久化的取舍和选择

redis持久化RDB

cfb1c88914262faf04d222f7a6fab63.png

触发机制

save阻塞的 文件策略:如果存在老的RDB文件,替换 时间复杂度O(n)

bgsave

1c3f2d2981b6b3cc9e6c716aa64fb13.png

save与bgsave

命令 save bgsave
IO类型 同步 异步
阻塞 是(阻塞发生再fork)
复杂度 O(n) O(n)
优点 不会消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fork,消耗内存

0ab41f1f75f7dcee6846e18cdd3da7a.png

# 配置redis.conf
 save 900 1
 save 300 10
 save 60 10000
 dbfilename dump.rdb
 dir ./
 stop-write-on-bgsave-error yes
 rdbcompression yes
 rdbchecksum yes
#最佳配置
 dbfilename dump-${port}.rdb        #指定对应哪个redis的备份
 dir /bigdiskpath       #指定具体文件目录
 stop-write-on-bgsave-error yes
 rdbcompression yes

触发机制

  1. 全量复制
  2. debug reload
  3. shutdown

RDB总结

  1. RDB是redis内存到硬盘的快照,用于持久化
  2. save通常会阻塞redis
  3. bgsave不会阻塞redis,但是会fork新进程
  4. save自动配置满足任一就会被执行
  5. 有些触发机制不容忽视

AOF

RDB有什么问题 耗时、耗性能 不可控、丢失数据

46d597f9f4517d5e79433e11c713344.png

cc8313a29e316f593af6e259d520fe6.png

AOF运行原理-创建

c8e704ae53b483522b5bf049454826c.png

AOF运行原理-恢复

95964585364d6e84200583f55bc870d.png

AOF的三种策略 always

711b0ed6fdb46d797a35236cbf0806f.png

everysec

3be9661b8ebcc9b7ec538fc726944b5.png

no

061b83916931404b0a51d855d4617ae.png

命令 always everysec no
优点 不丢失数据 每秒一次fsync丢一秒数据 不用管
缺点 IO开销较大,一般的sata盘只有几百TPS 丢一秒数据 不可控

AOF重写

  • 减少硬盘占用量
  • 加速回复速度
  • dc5042eb30de199a3c06ac7e938f60e.png

AOF重写2种方式

  • bgrewriteaof命令
  • f3d835c4e8d588082c171d922a98680.png
  • 自动
配置名 含义
auto-aof-rewrite-min-size AOF文件重写需要的尺寸
auto-aof-rewrite-percentage AOF文件增长率
统计名 含义
aof_current_size AOF当前尺寸(单位:字节)
aof_base_size AOF上次启动和重写的尺寸(单位:字节)
  • 自动触发实际(同时满足)
  • aof_current_size > auto-aof-rewrite-min-size
  • aof_current_size - aof_base_size/aof_base_size > auto-aof-rewrite-percentage
#配置redis.conf
appendonly yes
appendfilename "appendonly-${port}.aof"
appendfsync everysec
dir /bigdiskpath
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

AOF重写流程

4daa4706e7eb5e6e0a852695b9327fb.png

AOF阻塞问题

89ace40a6a0566267d274c95b8b7640.png

大于2秒会造成主线程阻塞,无法进行后续客户端发来的命令 每秒刷盘的策略不止是只丢失1秒的数据,也有可能是几秒

如何定位

  • Redis日志
  • reids命令info Persistence(无法看到具体时间点)
  • linux top 命令观察IO使用率

RDB和AOF选择

命令 RDB AOF
启动优先级
体积
恢复速度
数据安全性 丢数据 根据策略决定
轻重

最佳策略

  • 小分片
  • 缓存或存储
  • 监控(硬盘、内存、负载、网络)
  • 足够的内存

fork操作

  1. 同步操作(阻塞)
  2. 与内存量息息相关:内存越大,耗时越长(与机器类型无关)
  3. info:latest_fork_usec

改善fork

  1. 优先使用物理机或者高效支持fork操作的虚拟化技术
  2. 控制redis实例最大可用内存:maxmemory
  3. 合理配置Linux内存分配策略:vm.overommit_memory=1
  4. 降低fork频率:例如放宽AOF重写自动触发机制,不必要的全量复制

子进程开销与优化

  1. CPU:
  • 开销:RDB和AOF文件生成,属于CPU密集型
  • 优化:不做主reids CPU绑定,不和密集型CPU部署在一起
  1. 内存
  • 开销:fork内存开销,Linux:copy-on-write
  • 优化:Linux:echo never > /sys/kernel/mm/transparent_hugepage/enabled(关闭增加fork速度)
  1. 硬盘
  • 开销:RDB和AOF文件写入,可以结合iostat,iotop分析
  • 优化:
  1. 不和高硬盘负载服务部署再一起:存储服务,消息队列等。
  2. no-appendfsync-on-rewrite = yes
  3. 根据写入量决定磁盘类型:例如SSD
  4. 单机多实例持久化文件目录可以考虑分盘存储

redis复制的原理与优化

单机有什么问题?机器故障 容量瓶颈 QPS瓶颈

27d529afd08b02db89c145eea87263c.png

简单总结

  1. 一个master可以有多个slave
  2. 一个slave只能有一个master
  3. 数据流向是单向的,master到slave

redis配置参数说明Redis主从复制和集群配置

slaveof ip port
slave-read-only yes
slaveof on one

全量复制

59d1ab8058fd7e31d9b999fcdd5ae09.png

开销:

  1. bgsave时间
  2. RDB文件网络传输时间
  3. 从节点清空数据时间
  4. 从节点加载RDB的时间
  5. 可能的AOF重写时间

部分复制

Redis主从复制和集群配置

ce4c3fc944010ef336388461b1b2ac4.png

主从复制的常见问题读写分离

  1. 读流量分摊到从节点,提高访问速度
  2. 可能遇到问题:复制数据延迟、读到过期数据、从节点故障

配置不一致

  1. 例如maxmemory不一致,丢失数据
  2. 例如数据结构优化参数(例如hash-max-ziplist-entries):内存不一致

规避全量复制

  1. 第一次全量复制
  • 第一次不可避免,从节点必须全量
  • 解决:小主节点(maxmemory)分数据量,访问低峰时刻
  1. 节点运行ID不匹配
  • 主节点重启(运行ID改变)
  • 解决:故障转移,例如哨兵或集群
  1. 复制积压缓冲区不足
  • 网络中断,部分复制无法满足
  • 解决:增大复制缓冲区配置rel_backlog_size,网络增强

规避复制风暴

  1. 单主节点复制风暴:
  • 问题:主节点重启,多从节点复制
  • 解决:更换复制拓扑
  • 9c651d680da6174d89f3a9ab358bd12.png
  • slave-1从master复制数据之后,接下来的slave都从slave-1复制数据,减轻master压力
  1. 单机器复制风暴
  • 如图:机器宕机后,大量全量复制
  • 主节点分散多机器
  • df70b83385db791fec09101b4cd453d.png

Redis Sentinel

主从复制-master宕掉故障处理

166a1cc6413c9ede_tplv-t2oaga2asx-zoom-in-crop-mark_4536_0_0_0.png

166a1ccd0082893c_tplv-t2oaga2asx-zoom-in-crop-mark_4536_0_0_0.png

Redis Cluster

缓存设计与优化

Redis云平台CacheCloud

阿里云Redis开发规范

内存管理

Redis 数据结构与内存管理策略(上)

Redis 数据结构与内存管理策略(下)

原理、方法双管齐下,大神带你细解Redis内存管理和优化

开发运维常见坑

redis调整内核参数

Redis安全

redis 热点Key的发现与解决之道

redis4.0之基于LFU的热点key发现机制



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
NoSQL 关系型数据库 MySQL
Redis私有云平台-Cachecloud安装和部署手册
Redis私有云平台-Cachecloud安装和部署手册
|
6月前
|
NoSQL Redis 索引
[Redis]——Redis命令手册set、list、sortedset
[Redis]——Redis命令手册set、list、sortedset
102 0
|
6月前
|
缓存 NoSQL 中间件
太卷了!京东、微博最新「Redis缓存高手心法手册」竟被开源了
众所周知,分布式架构被广泛应用于企业级应用开发中,以满足高并发、高可用、高性能、高扩展性等要求。 像电商平台秒杀、平台抢票等高并发场景,数据访问量激增,容易造成服务器负载过重从而导致崩溃。因此,分布式缓存作为分布式架构的重要组件,当一个缓存服务节点挂掉,可以马上切换到另外的缓存服务节点,以保证系统能正常运行。 而在缓存中间件中,Redis以兼具缓存和数据库的优点,适用范围更广,很多人更愿意使用,memcache也只能望其项背。
108 1
|
缓存 NoSQL 中间件
太卷了!京东、微博最新「Redis缓存高手心法手册」竟被开源了
众所周知,分布式架构被广泛应用于企业级应用开发中,以满足高并发、高可用、高性能、高扩展性等要求。
“阿里味”的「Redis核心实践全彩手册」给你,还学不会就转行吧
面过大厂资深技术岗的人都知道,Redis 基本上是必考点。比如: · Redis 常见的性能问题有哪些?该如何解决?——性能相关 · Redis 缓存的雪崩、击穿、穿透到底是什么意思?如何应对?——缓存相关 · Redis 主从集群常见的问题有哪些?该如何解决?——可用性相关 · 现有 Redis 实例,保存数量 6GB,未来预计会扩展到 32GB,请你提供一个解决方案,并分析它优点和潜在问题?——可扩展性相关
|
存储 NoSQL Redis
Redis超详细入门手册教程!还不快来看看?3
Redis超详细入门手册教程!还不快来看看?
97 1
|
存储 监控 NoSQL
Redis超详细入门手册教程!还不快来看看?4
Redis超详细入门手册教程!还不快来看看?
250 0
|
存储 JSON NoSQL
Redis超详细入门手册教程!还不快来看看?2
Redis超详细入门手册教程!还不快来看看?
123 0
|
存储 SQL JSON
Redis超详细入门手册教程!还不快来看看?1
Redis超详细入门手册教程!还不快来看看?
193 0
|
存储 NoSQL 算法
Redis数据类型选型手册
CSAPP 中的优化程序的性能章节中提到过,选择合适的算法和数据结构是优化程序的方向之一。Redis 官网中也明确提到,Redis 拥有突出的表现,不仅是因为它在内存中操作,还因为它的键值对都是按一定的数据结构来组织的,并最终对这些数据结构进行增删改查的操作。所以高效的数据结构是 Redis 拥有高性能的基石。
108 0