深入剖析Redis系列(五) - Redis数据结构之字符串

前言

字符串类型Redis 最基础的数据结构。字符串类型 的值实际可以是 字符串简单复杂 的字符串,例如 JSONXML)、数字(整数、浮点数),甚至是 二进制(图片、音频、视频),但是值最大不能超过 512MB

其他文章

  • 深入剖析Redis系列(一) - Redis入门简介与主从搭建

  • 深入剖析Redis系列(二) - Redis哨兵模式与高可用集群

  • 深入剖析Redis系列(三) - Redis集群模式搭建与原理详解

  • 深入剖析Redis系列(四) - Redis数据结构与全局命令概述

  • 深入剖析Redis系列(五) - Redis数据结构之字符串

  • 深入剖析Redis系列(六) - Redis数据结构之哈希

  • 深入剖析Redis系列(七) - Redis数据结构之列表

  • 深入剖析Redis系列(八) - Redis数据结构之集合

正文

1. 相关命令

1.1. 常见命令

1.1.1. 设置值

set key value [ex seconds] [px milliseconds] [nx|xx]

set 命令有几个选项:

  1. ex seconds:为 设置 秒级过期时间
  2. px milliseconds:为 设置 毫秒级过期时间
  3. nx:键必须 不存在,才可以设置成功,用于 添加
  4. xx:与 nx 相反,键必须 存在,才可以设置成功,用于 更新

除了 set 选项,Redis 还提供了 setexsetnx 两个命令:

setex key seconds value setnx key value

  • setex:设定键的值,并指定此键值对应的 有效时间
127.0.0.1:6379> setex key1 5 value1
OK
127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> get key1
(nil)复制代码
  • setnx:键必须 不存在,才可以设置成功。如果键已经存在,返回 0
127.0.0.1:6379> set key2 value1
OK
127.0.0.1:6379> setnx key2 value2
(integer) 1
127.0.0.1:6379> get key2
"value1"
复制代码

1.1.2. 获取值

get key

如果要获取的 键不存在,则返回 nil)。

127.0.0.1:6379> get not_exist_key
(nil)
复制代码

1.1.3. 批量设置值

mset key value [key value ...]

下面操作通过 mset 命令一次性设置 4键值对

127.0.0.1:6379> mset a 1 b 2 c 3 d 4
OK
复制代码

1.1.4. 批量获取值

mget key [key ...]

通过下面操作 批量获取abcd 的值:

127.0.0.1:6379> mget a b c d
1) "1"
2) "2"
3) "3"
4) "4"
复制代码

批量操作 命令,可以有效提高 开发效率,假如没有 mget 这样的命令,要执行 nget 命令的过程和 耗时 如下:

n次get时间 = n次网络时间 + n次命令时间

使用 mget 命令后,执行 nget 命令的过程和 耗时 如下:

n次get时间 = 1次网络时间 + n次命令时间

Redis 可以支撑 每秒数万读写操作,但这指的是 Redis 服务端 的处理能力,对于 客户端 来说,一次命令除了 命令时间 还是有 网络时间

假设 网络时间1 毫秒,命令时间为 0.1 毫秒(按照每秒处理 1 万条命令算),那么执行 1000get 命令和 1mget 命令的区别如表所示:

操作时间
1000次get操作1000 * 1 + 1000 * 0.1 = 1100ms = 1.1s
1次mget操作1 * 1 + 1000 * 0.1 = 101ms = 0.101s

1.1.5. 计数

incr key

incr 命令用于对值做 自增操作,返回结果分为三种情况:

  • 值不是 整数,返回 错误
  • 值是 整数,返回 自增 后的结果。
  • 键不存在,按照值为 0 自增,返回结果为 1
127.0.0.1:6379> exists key
(integer) 0
127.0.0.1:6379> incr key
(integer) 1
复制代码

除了 incr 命令,Redis 还提供了 decr自减)、incrby自增指定数字)、decrby自减指定数字)、incrbyfloat自增浮点数)等命令操作:

decr key incrby key increment decrby key decrement incrbyfloat key increment

很多 存储系统编程语言 内部使用 CAS 机制实现 计数功能,会有一定的 CPU 开销。但在 Redis 中完全不存在这个问题,因为 Redis单线程架构,任何命令到了 Redis 服务端 都要 顺序执行

1.2. 不常用命令

1.2.1. 追加值

append key value

append 可以向 字符串尾部 追加值。

127.0.0.1:6379> get key
"redis"
127.0.0.1:6379> append key world
(integer) 10
127.0.0.1:6379> get key
"redisworld"
复制代码

1.2.2. 字符串长度

strlen key

比如说,当前值为 redisworld,所以返回值为 10

127.0.0.1:6379> get key
"redisworld"
127.0.0.1:6379> strlen key
(integer) 10
复制代码

1.2.3. 设置并返回原值

getset key value

getsetset 一样会 设置值,但是不同的是,它同时会返回 键原来的值,例如:

127.0.0.1:6379> getset hello world
(nil)
127.0.0.1:6379> getset hello redis
"world"
复制代码

1.2.4. 设置指定位置的字符

setrange key offeset value

下面操作将值由 pest 变为了 best

127.0.0.1:6379> set redis pest
OK
127.0.0.1:6379> setrange redis 0 b
(integer) 4
127.0.0.1:6379> get redis
"best"
复制代码

1.2.5. 获取部分字符串

getrange key start end

startend 分别是 开始结束偏移量偏移量0 开始计算,例如获取值 best前两个字符 的命令如下:

127.0.0.1:6379> getrange redis 0 1
"be"
复制代码

最后给出 字符串 类型命令的 时间复杂度 说明:

2. 内部编码

字符串 类型的 内部编码3 种:

  • int8 个字节的 长整型

  • embstr小于等于 39 个字节的字符串。

  • raw大于 39 个字节的字符串。

Redis 会根据当前值的 类型长度 决定使用哪种 内部编码实现

  • 整数类型
127.0.0.1:6379> set key 8653
OK
127.0.0.1:6379> object encoding key
"int"
复制代码
  • 短字符串
#小于等于39个字节的字符串:embstr
127.0.0.1:6379> set key "hello,world"
OK
127.0.0.1:6379> object encoding key
"embstr"
复制代码
  • 长字符串
#大于39个字节的字符串:raw
127.0.0.1:6379> set key "one string greater than 39 byte........."
OK
127.0.0.1:6379> object encoding key
"raw"
127.0.0.1:6379> strlen key
(integer) 40
复制代码

3. 典型使用场景

3.1. 缓存功能

下面是一种比较典型的 缓存 使用场景,其中 Redis 作为 缓存层MySQL 作为 存储层,绝大部分请求的数据都是从 Redis 中获取。由于 Redis 具有支撑 高并发 的特性,所以缓存通常能起到 加速读写降低后端压力 的作用。

整个功能的伪代码如下:

public UserInfo getUserInfo(long id) {String userRedisKey = "user:info:" + id;String value = redis.get(userRedisKey);UserInfo userInfo;    if (value != null) {userInfo = deserialize(value);     } else {        userInfo = mysql.get(id);   if (userInfo != null) { redis.setex(userRedisKey, 3600, serialize(userInfo));}return userInfo;}
}
复制代码

3.2. 计数

许多应用都会使用 Redis 作为 计数 的基础工具,它可以实现 快速计数查询缓存 的功能,同时数据可以 异步落地 到其他 数据源。一般来说,视频播放数系统,就是使用 Redis 作为 视频播放数计数 的基础组件,用户每播放一次视频,相应的视频播放数就会自增 1

public long incrVideoCounter (long id) {String key = "video:playCount:" + id;return redis.incr(key);
}
复制代码

实际上,一个真实的 计数系统 要考虑的问题会很多:防作弊、按照 不同维度 计数,数据持久化底层数据源等。

3.3. 共享Session

一个 分布式 Web 服务将用户的 Session 信息(例如 用户登录信息)保存在 各自 的服务器中。这样会造成一个问题,出于 负载均衡 的考虑,分布式服务 会将用户的访问 均衡 到不同服务器上,用户 刷新一次访问 可能会发现需要 重新登录,这个问题是用户无法容忍的。

为了解决这个问题,可以使用 Redis 将用户的 Session 进行 集中管理。在这种模式下,只要保证 Redis高可用扩展性的,每次用户 更新 或者 查询 登录信息都直接从 Redis 中集中获取。

3.4. 限速

很多应用出于安全的考虑,会在每次进行登录时,让用户输入 手机验证码,从而确定是否是用户本人。但是为了 短信接口 不被 频繁访问,会 限制 用户每分钟获取 验证码 的频率。例如一分钟不能超过 5 次,如图所示:

此功能可以使用 Redis 来实现,伪代码如下:

String phoneNum = "138xxxxxxxx";
String key = "shortMsg:limit:" + phoneNum;
// SET key value EX 60 NX
boolean isExists = redis.set(key, 1, "EX 60", "NX");
if (isExists != null || redis.incr(key) <= 5) {// 通过
} else {// 限速
}
复制代码

上述就是利用 Redis 实现了 限速功能,例如 一些网站 限制一个 IP 地址不能在 一秒钟之内 访问超过 n 次也可以采用 类似 的思路。

小结

本文简单的介绍了 Redis字符串数据结构基本命令内部编码相关应用场景

参考

《Redis 开发与运维》


欢迎关注技术公众号: 零壹技术栈

本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全新升级的AOP框架Dora.Interception[6]: 框架设计和实现原理

本系列前面的五篇文章主要介绍Dora.Interception的编程模式以及对它的扩展定制&#xff0c;现在我们来聊聊它的设计和实现原理。目录一、调用链抽象二、基于约定的拦截器定义三、基于调用上下文的依赖注入容器四、拦截器的提供五、调用链的构建六、方法拦截的实现原理七、依赖注…

activemq 安全连接

一、定义用户组1.1 simpleAuthenticationPlugin通过在activemq.xml中配置用户组<plugins> <simpleAuthenticationPlugin> <users> <authenticationUser username"admin" password"password" groups"admins,publishers,consumer…

React Native在Android当中实践(五)——常见问题

React Native在Android当中实践&#xff08;一&#xff09;——背景介绍 React Native在Android当中实践&#xff08;二&#xff09;——搭建开发环境 React Native在Android当中实践&#xff08;三&#xff09;——集成到Android项目当中 React Native在Android当中实践&#…

完成登录与注册页面的前端

完成登录与注册页面的HTMLCSSJS&#xff0c;其中的输入项检查包括&#xff1a; 用户名6-12位 首字母不能是数字 只能包含字母和数字 密码6-12位 注册页两次密码是否一致 JS&#xff1a; function fnLogin() {var uSer document.getElementById("user");var pAss do…

mysql505复位密码_mysql5 如何复位根用户密码[官方文档]

如何复位根用户密码如果你从未为MySQL设置根用户密码&#xff0c;服务器在以根用户身份进行连接时不需要密码。但是&#xff0c;建议你为每个账户设置密码如果你以前设置了根用户密码&#xff0c;但却忘记了该密码&#xff0c;可设置新的密码。下述步骤是针对Windows平台的。在…

WPF效果第二百零一篇之实现合并单元格

早一段时间又一次出差青海省西宁市;回来又是总结又是各种琐事,也没顾得上去分享点东西;大周末的就在家分享一下,这二天再次基于ListBox实现的合并单元格的效果:1、ListBox嵌套ListBox的前台布局:<ListBox ItemsSource"{Binding LCPListData}" x:Name"Manufac…

转载 maven 详解 http://www.cnblogs.com/binyue/p/4729134.html

--声明规范 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!--声…

ASP.NET Core中使用EasyCaching作为缓存抽象层

简介做后端开发&#xff0c;缓存应该是天天在用&#xff0c;很多时候我们的做法是写个帮助类&#xff0c;然后用到的时候调用一下。这种只适合简单层次的应用&#xff1b;一旦涉及到接口实现调整之类的&#xff0c;这种强耦合的做法很不合适。有些其他的功能又要去重复造轮子。…

mysql qps如何查看_mysql状态查看 QPS/TPS/缓存命中率查看

运行中的mysql状态查看对正在运行的mysql进行监控&#xff0c;其中一个方式就是查看mysql运行状态。(1)QPS(每秒Query量)QPS Questions(or Queries) / uptimemysql > show global status like Question%;mysql > show global status like uptime%;(2)TPS(每秒事务量…

visual studio开启多核编译方法

先按http://blog.csdn.net/acaiwlj/article/details/50240625的方法进行了VS多线程的启动。 原本以为按以下步骤设置就OK了&#xff0c;但是编译中无意间发些了一个warning&#xff1a;“/Gm”与多处理不兼容&#xff1b;忽略 /MP 开关&#xff01;&#xff01;&#xff01;&am…

聊聊storm nimbus的LeaderElector

为什么80%的码农都做不了架构师&#xff1f;>>> 序 本文主要研究一下storm nimbus的LeaderElector Nimbus org/apache/storm/daemon/nimbus/Nimbus.java public static void main(String[] args) throws Exception {Utils.setupDefaultUncaughtExceptionHandler();…

Android框架式编程之BufferKnife

BufferKnife作为框架式编程的重要组成部分&#xff0c;使用BufferKnife能够极大的精简View层面的代码量&#xff0c;并为MVP/MVC方式提供辅助。 一、配置 compile com.jakewharton:butterknife:(insert latest version) annotationProcessor com.jakewharton:butterknife-compi…

如果我去深圳,你会见我吗

▲图/ 深圳夜景初次见易小姐&#xff0c;还是21年的春节回老家的时候。想来20年因为疫情没有回家&#xff0c;家母几次三番电话里头表达的思念以及建议一些不靠谱的回家计划&#xff0c;着实有些不忍&#xff0c;确实有似“儿行千里母担忧”之理&#xff0c;索性拿着年假和加班…

CodeForces - 1059D(二分+误差)

链接&#xff1a;CodeForces - 1059D 题意&#xff1a;给出笛卡尔坐标系上 n 个点&#xff0c;求与 x 轴相切且覆盖了所有给出点的圆的最小半径。 题解&#xff1a;二分半径即可。判断&#xff1a;假设当前二分到的半径是 R &#xff0c;因为要和 x 轴相切&#xff0c;所以圆心…

pureref 平移用不了_关于参考图管理神器 PureRef 的一些快捷键

PureRef 的一些快捷键 软件下载&#xff1a;点击这里控制(配合左键)窗口内鼠标左键     框选窗口边鼠标左键     调整窗口大小鼠标中键 或 按住Alt     移动画布鼠标滚轮 或 按住Z     缩放画布按住S     查看目标位置颜色信息(可复制16进制颜色…

Windows 10 版本信息

Windows 10 版本信息 原文 https://technet.microsoft.com/zh-cn/windows/release-info Windows 10 版本信息 Microsoft 已更新其服务模型。 半年频道每年发布两次功能更新&#xff0c;时间大概在 3 月和 9 月&#xff0c;每个版本的服务时间线为 18 个月。 从 Windows 10 版本…

开源轻量的 .NET 监控工具 - 看门狗

你好&#xff0c;这里是 Dotnet 工具箱&#xff0c;定期分享 Dotnet 有趣&#xff0c;实用的工具或组件&#xff0c;希望对您有用&#xff01;简介WatchDog 是一个使用 C# 开发的开源的轻量监控工具&#xff0c;它可以记录和查看 ASP.Net Core Web 和 WebApi 的实时消息、事件、…

python读取oracle数据库性能_用python对oracle进行简单性能测试

一、概述dba在工作中避不开的两个问题&#xff0c;sql使用绑定变量到底会有多少的性能提升&#xff1f;数据库的审计功能如果打开对数据库的性能会产生多大的影响&#xff1f;最近恰好都碰到了&#xff0c;索性做个实验。sql使用绑定变量对性能的影响开通数据库审计功能对性能的…

BZOJ 3231: [Sdoi2008]递归数列 (JZYZOJ 1353) 矩阵快速幂

http://www.lydsy.com/JudgeOnline/problem.php?id3231和斐波那契一个道理在最后加一个求和即可1 #include<cstdio>2 #include<cstring>3 #include<iostream>4 //using namespace std;5 const int maxn10010;6 const double eps1e-8;7 long long modn;8 lon…

马斯克的火箭上天了,SpaceX开源项目也登上了热榜!

python知识手册SpaceX于美国东部时间5月30日下午3&#xff1a;22分将两位美国宇航员送往国际空间站&#xff0c;虽然这只是Demo任务&#xff0c;但SpaceX已经以其卓越工程优势、低廉的发射成本赢得了全球航天产业的信赖。同时也是除美俄中这些航天国家队以外&#xff0c;唯一独…