Redis集群教程(Redis cluster tutorial)

2023-10-27

本博文翻译自Redis官网:http://redis.io/topics/cluster-tutorial

       本文档以温和的方式介绍Redis集群,不使用复杂的方式来理解分布式系统的概念. 它介绍了如何建立、测试和使用一个集群,没有详细的覆盖Redis集群说明书 ,只是从用户的角度描述了系统的特性.
不管怎么样,本教程尝试从最终用户的角度来提供关于Redis 集群 可用性和一致性的信息。
注意:本教程需要Redis 3.0版本或者更高.
如果你计划运行一个重要的Redis 集群部署,更多的正规说明书建议阅读下,虽然不严格要求.    不管怎样,这是一个好的建议从本文档开始玩转Redis 集群一段时间,稍后阅读Redis 集群详细说明书.

一、Redis集群101

Redis集群提供一个将数据通过多个Redis节点自动分片的方式来安装Redis.
Redis集群也通过分区提供可用性程度,那就是在实践中当一些节点down掉或失去联系,仍然可以继续工作的能力. 不管怎样,大量节点出现故障时(例如当大多数的主节点不可用)Redis集群会停止工作.
所以在实践中,你从Redis集群中得到了什么?
  • 在多个节点中数据自动分片的能力.
  • 当一部分节点失败或者不能与集群其余节点通信 ,集群仍然可以工作的能力.

二、Redis集群TCP端口

每个Redis集群节点需要开通两个TCP 连接。正常的Redis TCP端口被用作服务端的端口,例如6379,服务端口加上10000得到的作为数据端口,例如16379。
第二个高端口被用于集群总线,即使用二进制协议的点对点的通信通道。  集群总线被节点用来作 失败探测、配置更新、故障转移授权认可等等。 客户端不应该尝试联系集群总线端口,但是总与正常的命令行端口连接。无论如何,确保这两个端口在你的防火墙是打开的,否则Redis集群节点不能互相联系.
命令行端口和集群总线端口的偏移量书固定的,总是10000.
注意为了让集群正确的工作,你需要为每个节点:
  1. 命令行端口对需要访问集群的客户端可达, 加上所有其余的集群节点(使用命令行端口做keys转移)。
  2. 集群总线端口(命令行端口+10000)对集群中的所有节点可达.
如果你不打开两个TCP端口,你的集群将不会预期的工作.
集群总线使用一个不同的、二进制协议来进行点对点的数据交换, 这种方式使用少量的带宽和处理时间使其更适合节点之前的数据交换.

三、Redis集群和Docker

当前的Redis集群不支持NATted (网路地址转换)环境和常规下IP地址或端口重新规划的环境。
Docker使用一个叫端口映射的技术:程序运行在Docker容器中可能暴露一个不同的端口给一认为比较信任的程序使用.  对于为了在同一端口、同一时间、同一服务运行多个服务是非常有用的。
为了使Docker和Redis集群更好的兼容,你需要使用Docker的主机网络模式(   host networking mode  ),请在 Docker文档是查看更多关于 --net=host选项的信息.

四、Redis集群数据分片

Redis集群不使用一致性Hash算法,使用另一种分片形式----- 每个key被概念性的区分,我们称之为Hash slot.
Redis集群有16384个hash slot,然后为了计算一个给定key的hash slot是什么,我们简单的采用了这个key的CRC16校验模16384得到.

每个Redis集群节点负责hash slots总数的的一个子集,举个例子,你拥有三个节点的Redis集群:

  • 节点A包含0~5500个hash slots.
  • 节点B包含5501~11000个hash slots.
  • 节点C包含11001~16383个hash slots.
这使得添加和和删除节点在Redis集群中变得容易.例如,如果我想加个节点D,我需要从节点A、B、C移动一些hash slot到D节点上. 同样的,如果我想从集群中移除节点A,我只需要把服务于A节点的hash slot移动到B和C.当节点A没有任何的hash slot时,就可以完全的删除节点A了.
因为从一个节点移动hash slots到另一个节点不需要停止操作、添加和删除节点、或者改变节点间持有hash slot的百分比,也不需要任何的服务停止.

Redis集群支持多key操作,只要所有的key在单一的命令行运行(或整个事务,或Lua脚本运行)所有的key属于同一个hash slot。 用户可以强制多key在同一个hash slot,通过使用一个叫hash tags的东西. 
Hash tags被记录在Redis 集群的规范说明书里. 但是主旨是如果有一个子串在方括号和一个key之间,只要方括号里的字符串是散列的,例如:  this{foo}key和another{foo}key
保证在同一个hash slot里,可以在同一个命令行窗口里多key操作作为参数使用。

五、Redis集群主从模型

当集群中的一部分主节点失败或不能与多数的节点通信,为了保持集群的可用行,Redis集群使用主从复制模型,每一个hash slot拥有1(主节点自身)到N(N-1额外的副节点)的复制.
在我们的例子中,节点A、B、C,如果集群中的节点B失败后,我们没有办法继续服务5501-11000范围的hash slot。
不管怎样,当一个集群被创建时(或之后的一段时间),我们为每一个主节点添加一个副节点,所以最终的集群A、B、C三个主节点和A1、B1、C1三个副节点组成,如果节点B出现故障时,集群仍然可以继续工作。
节点B1代替了节点B,B失败了,集群会提升节点B1作为新的主节点,集群将会继续正常工作.
注意:如果集群中的节点B和B1同时失败了,集群将不会继续工作.

六、Redis集群一致性保证

Redis集群不能保证较强的一致性。在实践中意味着,当前条件下,Redis 集群会丢失写的数据---系统被客户端承认.
Redis集群丢失写数据的首要原因是它使用了异步复制. 这就意味着你写数据的时候会有如下情况发生:
  • 你的客户端写数据到主节点B.
  • 主节点B回应你的客户端一切OK.
  • 主节点复制写的数据到副节点B1、B2、B3.
就你所看见的,主节点B在回应客户端之前不会等待B1、B2、B3的确认,所以这对Redis集群将是一个潜在的隐患. 所以你的客户端写了一些东西,节点B对写操作进行确认,但是节点B这时候出现故障down了,副本节点的其中一个(数据没有写入的那个节点)将会被提升为主节点,永远的丢失刚写入的数据.
这跟大多数数据库配置每秒刷新数据到磁盘很相似。所以设想下你已经知道原因,通过使用传统数据库的过去经验,没有涉及分布式系统。同样的,你可以强制数据库刷新数据到磁盘在回应客户端之前来提供数据的一致性,但是通常的结果是降低系统的性能。 这个例子等价于Redis集群的异步复制.
基本上,需要把性能和一直性权衡考虑.
Redis集群支持同步写当绝对需要的时候,通过 WAIT命令实现, 这使得写数据丢失率少一点。不管怎样,值得注意的是Redis集群不实现强一致性,即使同步复制操作被使用 :更复杂的失败场景总是可能的,当一个副节点没有接收到数据之前已经被选为主节点了.
这里有一个值得注意的Redis将会丢失数据的场景 ,发生在网路分区时,一个客户端和一些实例连接,连接的实例中至少包含一个主节点.
就拿我们由A,B,C,A1,B1,C1 6个节点组成的集群作为例子,3主点,3个副节点。还有一个客户端,我们称它为Z1.
分区出现后,可能的情况是,在分区的一面有A,C,A1,B1,C1,在另一面有B和Z1。
Z1仍然可以写数据到B,B也可以接收到Z1写的数据。如果分区在较短时间内恢复完成,集群可以正常的工作.然而,如果分区持续足够时间让大分区的B1节点成为主节点,Z1写到B的数据将会丢失.
有一点注意的是Z1写数据到B的数量有一个最大值窗口:如果足够时间的流失,使得拥有较多节点的那一个分区中的一个副节点被选举为主节点,拥有较少节点分区里的主节点将停止接收数据的写入。
节点超时时间在Redis集群中是一个非常重要的配置指令. 节点超时时间过去之后,一个主节点被认为失败,可能会被它副节点其中的一个代替.同样的,节点超时时间过去之后,没有一个主节点可以感知到其它主节点的大多数,它将进入一个错误的状态、停止数据的写入.

七、Redis集群配置参数

我们打算创建一个集群部署的样例。在继续之前,让我们先介绍下Redis 集群配置文件redis.conf 的一些配置参数. 一些参数是很显然的,另一些参数在你继续阅读之后将变的更清晰。

  • cluster-enabled <yes/no>:如果是设置为yes,Redis集群将支持一个指定的Redis实例;否则这个实例将作为一个普通单独的实例。
  • cluster-config-file <filename>注意不要管这个选项的名称,这不是一个用户编辑的配置文件,而是Redis集群自动存留的Redis配置(状态,基本的)每当集群发生变化时,为了在启动时再次读取. 这个文件列出了其他节点在集群中的状态、持久性变化等等。这个文件常常在磁盘上重写、刷新作为一些消息接收的结果.
  • cluster-node-timeout <milliseconds>:Redis集群中的点不用,被认为失败节点的的最大等待时间。如果一个主节点在指定的时间段内不可达,就会被他的副节点做失败处理. 这个参数控制Redis集群中其它重要事情。尤其,每个节点不能在指定时间内与主节点中的大多数通信,该节点将会停止查询。
  • cluster-slave-validity-factor <factor>:如果设置成0,一个副节点总是尝试FailOver主节点,不管主节点和副节点保持断开连接多长时间。如果这个值设置为正数,一个最大失联时间将会被计算出来,node-timeout 乘以这个选项配置的factor, 如果这个节点是副节点,它将不会启动Failover当失联超过计算出的指定时间。 例如,如果node-timeoutt设置为5秒,validity factor 设置为10,一个副节点与主节点失去联系超过50秒后,副节点将不会尝试Failover它的主节点。注意,任何不同于0的值将导致集群不可用,当一个主节点失败后, 没有副节点可以替换它。在那个例子中,集群将返回可用,只要原始的主节点重新加入到集群中.
  • cluster-migration-barrier <count>:  一个主节点最少副节点连接数目,另一个移动到一个不被任何副节点覆盖的主节点。阅读本教程更多关于对于副本迁移恰当分区的信息.
  • cluster-require-full-coverage <yes/no>:如果设置为yes,默认的,如果一定比例的key空间不被任何节点覆盖,集群将停止消息的写入;如果设置为no,集群仍然支持查询服务即使只有一部分key处理请求.

八、创建和使用一个Redis集群

注意:手工部署一个Redis集群,学习集群的特定操作是非常重要的。不管怎样,如果你想快速的运行一个集群,跳过这一部分 ,你可以阅读下一部分 创建一个Redis集群使用create-cluster脚本。
创建一个集群,首先我们要有一些以集群模式运行的空的Redis实例。这基本意味着集群不是用正常的Redis实例创建的,但是一个特殊的模式需要被配置将使Redis实例拥有集群指定的属性和命令。
如下是一个集群配置文件最少的配置项:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
就你所知,使集群模式工作只需要一个简单的cluster-enabled指令。每个实例也包含该节点配置信息被存储的文件的路径,默认是nodes.conf。 该配置文件不会被手动更改,它仅仅在Redis 集群实例启动的时候生成,每次需要的时候更新这个文件。
注意期望最小集群工作,要求至少三个主节点。对于你第一次测试,强烈建议你开启一个6个节点的集群,包含3个主节点和3个副节点。
就这样做,进入一个新的目录,创建如下以端口号命令的目录:
mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005
在7000到7005每个目录下面,创建一个Redis.conf文件。你配置文件的模板只要使用上面小例子的内容就可以了,但是要确保替换port 7000 右边的port  数字和你目录名字保持一致.
现在把在GitHub上不稳定分支编译好的可以执行redis-server 源文件复制到 cluster-test目录下面,最后打开6个终端标签在你最喜欢的终端应用上.
向这样开始每个实例,在每个终端标签上:
cd 7000
../redis-server ./redis.conf
你可以看见每个实例的日志,由于 nodes.conf文件不存在,每个节点分配一个新的ID.
[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1
这个ID将被指定的Redis 实例永远使用,为了让这个实例在Redis上下文中有一个唯一的名字. 每一个节点都是通过ID来记录其余的节点,而不是通过IP地址或端口。 IP地址和端口可以改变,但是这个节点唯一的节点标识在节点生命周期内永远不会改变。我们把这个标识简单的称之为节点ID.

1、创建集群

现在我们有一个实例在运行,我们需要写一些对节点有意义的配置来创建集群。 这个很容易完成通过Redis集群命令行工具---redis-trib,一个Ruby程序执行在实例上执行特殊的命令来创建Redis集群、检查或分片一个已存在的集群等等。
redis-trib工具分配在Redis源代码目录下的src目录下。你需要安装  redis gem 使运行redis-trib成为可能。
gem install redis
创建集群的简单类型
./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
这里使用的命令是creat,因为我们想创建一个新的Redis集群。   --replicas 1 这个选项的意思是我们想要为每个master节点创建一个slave节点,其余参数是我想创建集群实例要使用的地址列表。
显然,集群是按照我们的要求建立的,3个master节点、3个slave节点。
Redis-trib将会提出一个配置,输入yes,集群将会被配置和加入,这意味着,Redis实例将会被引导至互相交互。最后,你将看到一个信息:
[OK] All 16384 slots covered
上面这条信息意味着,至少有一个master节点实例服务于16384 slot 中的每一个。

2、使用create-cluster脚本创建Redis集群

如果你不想通过手工的配置和执行单独的实例来创建Redis集群,就像上面解释的那样。这里有一个更简单的方法(但是你不必学习相同数量的操作细节)。
只要查看下Redis分布的utils/create-cluster 目录下,这里有一个叫做create-cluster的脚本(和包含这个脚本的目录名称相同),它是一个简单的bash脚本。为了开始6个节点的集群(3个master节点,3个slave节点) ,只要输入如下命令:
1、create-cluster start
2、create-cluster create
第二步的时候,当redis-trib工具想让你接受redis集群布局时,请输入yes。
现在你能够和Redis集群相互作用,第一个节点默认在30001端口启动。当你完成,使用下面命令停止Redis集群:
create-cluster stop.
请阅读目录下面的README 文件查看更多关于运行该脚本的信息.

3、玩转Redis集群(Playing with the cluster)

在这个阶段,Redis集群的一个问题是缺少客户端库的实现。
我知道如下的实现:
redis-rb-cluster is a Ruby implementation written by me (@antirez) as a reference for other languages. It is a simple wrapper around the original redis-rb, implementing the minimal semantics to talk with the cluster efficiently.
redis-py-cluster A port of redis-rb-cluster to Python. Supports majority of redis-py functionality. Is in active development.
The popular Predis has support for Redis Cluster, the support was recently updated and is in active development.
The most used Java client, Jedis recently added support for Redis Cluster, see the Jedis Cluster section in the project README.
StackExchange.Redis offers support for C# (and should work fine with most .NET languages; VB, F#, etc)
thunk-redis offers support for Node.js and io.js, it is a thunk/promise-based redis client with pipelining and cluster.
redis-go-cluster is an implementation of Redis Cluster for the Go language using the Redigo library client as the base client. Implements MGET/MSET via result aggregation.
The redis-cli utility in the unstable branch of the Redis repository at GitHub implements a very basic cluster support when started with the -c switch.
一个简单的方式来测试你的集群是使用上面任何一种客户端或者简单的命令行工具redis-cli。
如下是一个使用redis-cli方式交互的例子:
$ redis-cli -c -p 7000
redis 127.0.0.1:7000> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:7002
OK
redis 127.0.0.1:7002> set hello world
-> Redirected to slot [866] located at 127.0.0.1:7000
OK
redis 127.0.0.1:7000> get foo
-> Redirected to slot [12182] located at 127.0.0.1:7002
"bar"
redis 127.0.0.1:7000> get hello
-> Redirected to slot [866] located at 127.0.0.1:7000
"world"


***************未完待续******************
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis集群教程(Redis cluster tutorial) 的相关文章

  • Express 和 Redis 会话的过期时间

    我正在使用express和redis来使会话在我的系统上保持活动状态 我在设置 sessionCookie 上的 maxAge 时遇到一些问题 默认情况下 我读到的时间是 24 小时 但这对于保持其存活来说是很长的时间 我想设置大约 30
  • Node.js 公牛队列中的作业陷入“等待”状态

    我有一堆工作在公牛队列中 其中一个被卡住了 1 个多小时 通常需要大约 2 分钟才能运行 但没有失败 我无法使用我使用的 bull arena UI 将作业从活动状态中删除 因此我删除了 Redis 中活动作业的密钥 这消除了卡住的活动作业
  • 以原子方式从 Redis 数据结构中弹出多个值?

    是否有一个 Redis 数据结构 允许弹出 获取 删除 其中包含的多个元素的原子操作 有众所周知的 SPOP 或 RPOP 但它们总是返回单个值 因此 当我需要 set list 中的前 N 个值时 我需要调用该命令 N 次 这是昂贵的 假
  • Node.js 与 Redis:同步还是异步?

    在我的应用程序 node express redis 中 我使用一些代码同时更新数据库中的多个项目 app put myaction function req res delete stuff db del key1 db srem set
  • Python Reddis 队列 ValueError:worker 无法处理 __main__ 模块中的函数

    我正在尝试使用 python rq 在 redis 中排队一项基本作业 但它会抛出此错误 ValueError 函数来自main模块无法被工作人员处理 这是我的程序 import requests def count words at ur
  • 如何判断sidekiq是否连接到redis服务器?

    使用控制台 如何判断 sidekiq 是否连接到 Redis 服务器 我希望能够做这样的事情 if sidekiq is connected to redis psuedo code MrWorker perform async do wo
  • 在节点中使用redis获取hash key的所有字段和值

    红色是使用哈希 我需要存储具有多个字段和值的哈希键 我尝试如下 client hmset Table1 Id 9324324 ReqNo 23432 redis print client hmset Table1 Id 9324325 Re
  • 连接到 localhost:6379 时出现错误 99。无法分配请求的地址

    设置 我有一个虚拟机 并在虚拟机中运行三个容器 一个 nginx 代理 一个非常简约的 Flask 应用程序和 redis Flask 应在端口 5000 上提供服务 而 redis 应在 6379 上提供服务 这些容器中的每一个都可以作为
  • Laravel - 缓存 Eloquent 并频繁更新

    是否可以对经常修改的对象使用缓存 例如 假设我们有一个 BlogPost 对象 并且有一个经常更改的 num of views 列 以及其他列 是否可以更新缓存和数据库中的 num of views 字段 而不破坏缓存对象并重新创建它 我可
  • connect-redis - 如何保护会话对象免受竞争条件影响

    我使用 nodejs 和 connect redis 来存储会话数据 我将用户数据保存在会话中 并在会话生命周期中使用它 我注意到两个更改会话数据的请求之间可能存在竞争条件 我尝试过使用 redis lock 来锁定会话 但这对我来说有点问
  • 如何在多个Lua State(多线程)之间传递数据?

    我在中启动Redis连接池redis lua 通过从 C 调用 我得到了redis lua state 此 Lua 状态全局启动一次 仅在其他线程中启动get从中 当有一个 HTTP 请求 工作线程 时 我需要从redis lua stat
  • 如何让客户端下载动态生成的非常大的文件

    我有一个导出功能 可以读取整个数据库并创建一个包含所有记录的 xls 文件 然后文件被发送到客户端 当然 导出完整数据库的时间需要大量时间 并且请求很快就会以超时错误结束 处理这种情况的最佳解决方案是什么 例如 我听说过使用 Redis 创
  • 如何使用Spring Cache处理redis异常?

    我目前正在开发一个包含 Spring Data Redis 和 Spring Cache 的项目 在spring data redis中 我使用redis模板调用redis 我在 try catch 块中处理 redis 模板抛出的所有异常
  • Redis键空间事件不触发

    我有两个 Redis 客户端 在一个文件中我有一个简单的脚本设置并删除了 Redis 键 var redis require redis var client redis createClient 6379 127 0 0 1 client
  • WSL Redis 遇到系统尚未使用 systemd 作为 init 系统(PID 1)启动。无法操作[已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试遵循本文中讨论的 Redis 安装过程article https www digitalocean com community
  • Spring Data Redis - Lettuce连接池设置

    尝试在 spring data redis 环境中设置 Lettuce 连接池 下面是代码 Bean LettuceConnectionFactory redisConnectionFactory GenericObjectPoolConf
  • Redis INCRBY 有限制

    我想知道是否有一种方法可以通过我的应用程序的单次往返在 Redis 中执行此操作 对于给定的键K 其可能值V是范围内的任意整数 A B 基本上 它有上限和下限 When an INCRBY or DECRBY发出命令 例如INCRBY ke
  • redis 阻塞直到 key 存在

    我是 Redis 新手 想知道是否有办法能够await get通过它的键来获取值 直到该键存在 最小代码 async def handler data await self fetch key async def fetch key ret
  • 如何测试我的 Redis 缓存是否正常工作?

    我已经安装了 django redis cache 和 redis py 我遵循了 Django 的缓存文档 据我所知 以下设置就是我所需要的 但我如何判断它是否正常工作 设置 py CACHES default BACKEND redis
  • 无法启动redis.service:单元redis-server.service被屏蔽

    我在 ubuntu 16 04 上安装了 Redis 服务器 但是当我尝试使用启动redis服务时 sudo systemctl start redis 我收到消息 Failed to start redis service Unit re

随机推荐

  • JS各种校验规则

    目录 1 校验是否为整数 2 验证开始时间是否大于结束时间 3 校验手机号是否正确 4 校验身份证是否合法 5 校验字符串是否为正整数 6 去除两端空白判断是否为空 7 校验邮箱是否合理 1 校验是否为整数 var flowNum flow
  • 微信支付服务器端代码,APP接入微信支付(后台代码)

    配置参数 private config array appid gt 微信开放平台上的应用id mch id gt 微信申请成功之后邮件中的商户id api key gt 在微信商户平台上自己设定的api密钥 32位 notify url
  • 祖传Python代码,初学者必用,含泪发出

    今天分享几段工作生活中常用的代码 都是最为基础的功能和操作 而且大多还都是出现频率比较高的 很多都是可以拿来直接 使用或者简单修改就可以放到自己的项目当中 日期生成 很多时候我们需要批量生成日期 方法有很多 这里分享两段代码 Python学
  • 华为HJ2 计算某字符出现次数

    a input b input num 0 for i in range len a if b lower a i lower num num 1 print num
  • CUDA基本优化方法

    一 基于编程模型和执行模型的优化方法 1 选取合适的gridDim和blockDim blockDim最好为32的整数倍 因为执行指令的基本单位为线程束 线程束内的所有线程统一执行广播下来的命令 而线程束的线程数量基本为32 当block被
  • xx排排网数据加密(js逆向)

    网址 aHR0cHM6Ly9kYy5zaW11d2FuZy5jb20v 点翻页看抓包信息 这个data就是加密后的数据 这里的key是一段代码 这是解密所需的key 先拿出来格式化看看 这个和加速乐的处理方法是一样的 把evel换成cons
  • 【Pygame经典合集】​​​​​​终极白给大招:让你玩儿到爽(附多款游戏源码)

    导语 嘿 我是木木子 关注我 跟我一起玩游戏啦 其实嘛 最近的话游戏的话实在是没什么可以写的了 很多游戏的话太难仿制起来很费时间 于是 就有了今天这篇小合集 哈哈哈 这是一个pygame的项目 内含4款单个游戏的哦 想玩那款玩儿那款的哈 今
  • RS485通讯接口定义图详解

    RS485采用差分信号负逻辑 2V 6V表示 0 6V 2V表示 1 RS485有两线制和四线制两种接线 四线制只能实现点对点的通信方式 现很少采用 现在多采用的是两线制接线方式 这种接线方式为总线式拓朴结构在同一总线上最多可以挂接32个结
  • docked --debug 功能

    docker不正常时使用查看 太好用了 bip Bridge IP 是Docker的配置选项之一 用于指定Docker守护进程创建的网络桥接接口的IP地址和子网掩码 在设置bip时 确保所指定的IP地址不以0结尾 当使用以0结尾的IP地址作
  • 移动app自动化测试工具发展历程--完整版

    最近在总结关于移动app的自动化测试的系列文章 本来想在7月份推出这个系列 但是又担心7月份的天气太热 开空调费油 所以索性 想到哪就整理到哪 持续的推出来吧 今天先把移动app自动化测试工具总结一下 我大概的搜索了一下 本站的大佬 整理的
  • (C语言)矩阵转置 (10分)

    将一个3 3矩阵转置 即行和列互换 输入格式 在一行中输入9个小于100的整数 其间各以一个空格间隔 输出格式 输出3行3列的二维数组 每个数据输出占4列 输入样例 1 2 3 4 5 6 7 8 9 输出样例 1 4 7 2 5 8 3
  • 自己造一个简易的IOC轮子

    简易的IOC流程编写笔记 首先先对这个小demo做一个说明 首先这个demo是很简易的 里面有一些可以优化的复杂点我设置了TODO 如果你有兴趣的话 可以自己去完善一下 写这个demo就是为了让自己对IOC的一个流程更加熟悉 对于刚开始学习
  • 【ROS工具】ROS基础学习

    ROS基础学习 1 基本介绍 2 实际操作 1 基本介绍 ROS Robot Operating System 是一个机器人操作系统 开始于2007 三个中长期支持版本 对应着Ubuntu的三个LTS版本如下 ROS术语 主节点 ros m
  • 1139 First Contact(unique函数,string.substr()函数)

    PTA 程序设计类实验辅助教学平台 用map套个set来实现邻接表 排序都免了 include
  • Android开发之Retrofit/OkHttp使用

    OkHttp 简介 OkHttp是时下最火的Http请求框架 其官网及源码地址如下 OkHttp官网地址 http square github io okhttp OkHttp源码地址 https github com square okh
  • .Net下正则匹配规则

    Net中常用的正则表达式选项 1 IgnoreCase 忽略大小写 匹配时不区分大小写 2 Multiline 多行模式 更改 和 的含义 使它们分别在任意一行的行首和行尾匹配 而不仅仅在整个字符串的开头和结尾匹配 在此模式下 的精确含意是
  • 寻找小数

    题目描述 有一个分数a b 你需要找到数字c在这个数的小数点后第一次出现的位置 输入格式 输入一行 包含三个整数a b c 输出格式 输出一个整数 如果不存在c 输出 1 样例输入 1 2 0 样例输出 2 约定 1 lt a
  • TCP并发服务器的编程实现

    TCP并发服务器的编程实现 1 基于TCP的服务器编程模型 创建通信端点 套接字 返回该端点的文件描述符 sfd socket 2 2 将sfd和本地的ip地址和端口号绑定 bind 2 3 将sfd设置为被动连接状态 监听客户端的到来 如
  • linux中docker报错:ERROR: Got permission denied while trying to connect to the Docker daemon socket。

    文章目录 一 问题描述 二 问题分析 三 解决方法 1 切换成root用户操作 这是最直接的方法 切换命令 2 添加docker的用户组 把当前用户加入组中 四 gpasswd命令用法 一 问题描述 在运行docker命令 如docker
  • Redis集群教程(Redis cluster tutorial)

    本博文翻译自Redis官网 http redis io topics cluster tutorial 本文档以温和的方式介绍Redis集群 不使用复杂的方式来理解分布式系统的概念 它介绍了如何建立 测试和使用一个集群 没有详细的覆盖Red