首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
您找到你想要的搜索结果了吗?
是的
没有找到

ODrive 通讯协议「建议收藏」

与ODrive进行通讯需要对通讯端点进行一系列操作。理论上,端点上的数据可以是以任何方式序列化的任何类型的数据。数据包采用默认的序列化方式,对于您自定义的数据包,您必须自己去进行反序列化。未来我们可能会提供序列化功能。可以通过从端点0读取JSON来枚举可用的端点,从理论上讲,每个接口都可以不同(实际上并没有这么做)。每个端点都可以被用来发送和接收字节数据,有效字节数据的含义在JSON中进行了定义。 例如,int32端点的输入和输出是4字节的小字节序表示。 通常,组合的读/写请求的约定是交换,即返回的值是旧值。 自定义的端点可能不符合这种要求。 该协议有基于数据包的版本和基于流的变体。 适当地使用每个变体。 例如,USB默认运行基于数据包,而UART运行基于字节流。

01

CRC校验算法详解「建议收藏」

CRC(Cyclic Redundancy Check)循环冗余校验是常用的数据校验方法,讲CRC算法的文章很多,之所以还要写这篇,是想换一个方法介绍CRC算法,希望能让大家更容易理解CRC算法。   先说说什么是数据校验。数据在传输过程(比如通过网线在两台计算机间传文件)中,由于传输信道的原因,可能会有误码现象(比如说发送数字5但接收方收到的却是6),如何发现误码呢?方法是发送额外的数据让接收方校验是否正确,这就是数据校验。最容易想到的校验方法是和校验,就是将传送的数据(按字节方式)加起来计算出数据的总和,并将总和传给接收方,接收方收到数据后也计算总和,并与收到的总和比较看是否相同。如果传输中出现误码,那么总和一般不会相同,从而知道有误码产生,可以让发送方再发送一遍数据。   CRC校验也是添加额外数据做为校验码,这就是CRC校验码,那么CRC校验码是如何得到的呢?   非常简单,CRC校验码就是将数据除以某个固定的数(比如ANSI-CRC16中,这个数是0x18005),所得到的余数就是CRC校验码。   那这里就有一个问题,我们传送的是一串字节数据,而不是一个数据,怎么将一串数字变成一个数据呢?这也很简单,比如说2个字节B1,B2,那么对应的数就是(B1<<8)+B2;如果是3个字节B1,B2,B3,那么对应的数就是((B1<<16)+(B2<<8)+B3),比如数字是0x01,0x02,0x03,那么对应的数字就是0x10203;依次类推。如果字节数很多,那么对应的数就非常非常大,不过幸好CRC只需要得到余数,而不需要得到商。   从上面介绍的原理我们可以大致知道CRC校验的准确率,在CRC8中出现了误码但没发现的概率是1/256,CRC16的概率是1/65536,而CRC32的概率则是1/2^32,那已经是非常小了,所以一般在数据不多的情况下用CRC16校验就可以了,而在整个文件的校验中一般用CRC32校验。   这里还有个问题,如果被除数比除数小,那么余数就是被除数本身,比如说只要传一个字节,那么它的CRC就是它自己,为避免这种情况,在做除法之前先将它移位,使它大于除数,那么移多少位呢?这就与所选的固定除数有关了,左移位数比除数的位数少1,下面是常用标准中的除数:   CRC8:多项式是X8+X5+X4+1,对应的数字是0x131,左移8位   CRC12:多项式是X12+X11+X3+X2+1,对应的数字是0x180D,左移12位   CCITT CRC16:多项式是X16+X12+X5+1,对应的数字是0x11021,左移16位   ANSI CRC16:多项式是X16+X15+X2+1,对应的数字是0x18005,左移16位   CRC32:多项式是X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1,对应数字是0x104C11DB7,左移32   因此,在得到字节串对应的数字后,再将数字左移M位(比如ANSI-CRC16是左移16位),就得到了被除数。   好了,现在被除数和除数都有了,那么就要开始做除法求CRC校验码了。CRC除法的计算过程与我们笔算除法类似,首先是被除数与除数高位对齐后,被除数减去除数,得到了差,除数再与差的最高位对齐,进行减法,然后再对齐再减,直到差比除数小,这个差就是余数。不过和普通减法有差别的是,CRC的加(减)法是不进(借)位的,比如10减01,它的结果是11,而不是借位减法得到的01,因此,实际上CRC的加法和减法所得的结果是一样的,比如10加01的结果是11,10减01的结果也是11,这其实就是异或操作。虽然说了这么多也不一定能说清楚,我们还是看一段CRC除法求余程序吧:

03

《Redis设计与实现》读书笔记(二十九) ——Redis集群执行命令与重新分片

《Redis设计与实现》读书笔记(二十九) ——Redis集群执行命令与重新分片 (原创内容,转载请注明来源,谢谢) 一、集群中执行命令 1、节点对命令的判断 当对集群的16384个槽都完成指派后,集群就上线,可以对集群进行操作。当客户端向节点发送数据库键有关的命令,接收命令的节点,会计算命令属于哪个槽,并检查槽是否指派给自己。 如果槽是该节点负责,则执行命令;如果不是,返回一个moved错误,指引客户端对正确的节点执行命令,客户端根据返回结果,会自动连接上相应的节点,再次执行命令。 2、计算键属于哪个

06

使用Redis实现高流量的限速器

Redis是生产环境中默默无闻的主力配置。它不常用作主要的数据存储,但它可存储和访问临时数据(度量,会话状态,缓存等损失可以容忍的数据)方面有一个甜蜜点,并且速度非常快,不仅提供了最佳性能,还通过一组有用的内置数据结构提供了高效的算法。它是现代技术栈中最常见的主要部件之一。 Stripe的限速器建立在Redis的基础之上,直到最近,他们都运行在Redis 的一个非常Hot的实例上。服务器上有用于故障转移的follower,但在任何时候,只有一个节点处理每个操作。 你不得不佩服这样的系统。各种消息称,Redis可以在一个节点上每秒处理一百万次操作 - 我们项目不需要那么多,但是也有很多操作。每个速率限制检查都需要运行多个Redis命令,并且每个API请求都要通过很多速率的限制器。一个节点每秒处理大约数十到数十万个操作。 我们最终通过迁移到10个节点的Redis群集来实现这个目标。对性能的影响可以忽略不计,我们现在有一个简单的配置开关可以实现水平可伸缩性。 操作的限制 在更换系统之前,应该理解导致原始故障的原因和结果。 Redis的一个值得理解的特性是:它是一个单线程程序。但是会有后台线程处理一些像删除对象这样的操作,实际上所有正在执行的操作都堵塞在访问单个流控制点上。理解这点相对容易--Redis需要保证操作的原子性(无论是单一命令MULTI,还是 EXEC),这是源于它一次只执行其中一个操作的事实。 这个单线程模型确实是我们的瓶颈。 面对失败 即使以最大容量运营,我们发现Redis也会非常优雅地降级。主要表现:从与Redis交谈通信的节点观察到的基线连接性错误率增加 - 为了容忍发生故障的Redis,它们受到连接和读取超时(约0.1秒)的限制,并且与过载主机无法无法建立连接。 Redis这种表现虽然不是最佳的,但大部分时间情况都是好的。只有当合法 用户能够成功进行身份验证并在底层数据库上运行昂贵的操作时,它才会成为一个真正的问题,因为我们的目标是拦截巨大的非法流量冲击(即数量级超过允许的限制)。 这些流量峰值会导致错误率的成比例增加,并且许多流量还应该被允许通过,因为限速器默认是允许在错误情况下通过请求。这会给后端数据库带来更大的压力,这种压力在过载时不会像Redis那样优雅地失败。很容易看到数据库分区几乎完全无法操作。 Redis Cluster的分片模型 Redis的核心设计价值在于速度,而Redis集群的构建方式不会对此产生影响。与许多其他分布式模型不同,在其输出响应成功信号时,Redis集群中的操作并未在多个节点上进行确认,而是更像是一组独立的Redis通过分散空间来分担工作负载。这牺牲了高可用性,有利于保持操作的快速性 - 与标准的Redis独立实例相比,针对Redis群集运行操作的额外开销可以忽略不计。 分片是根据key进行的,可能的key总数分为16,384个插槽。key的插槽是通过稳定的哈希散列函数计算的,所有客户端都知道该如何操作: HASH_SLOT = CRC16(key) mod 16384 例如,如果我们想执行GET foo,我们会得到foo的以下插槽号: HASH_SLOT = CRC16("foo") mod 16384 = 12182 集群中的每个节点将处理16,384个插槽中的一部分,确切数量取决于节点数量。节点彼此通信以协调插槽分配以及可用性和插槽的再平衡。 客户端使用该CLUSTER系列命令来查询群集的状态。一个常见的操作是CLUSTER NODES获得插槽到节点的映射,其结果通常在本地缓存,并保持数据新鲜。 127.0.0.1:30002 master - 0 1426238316232 2 connected 5461-10922 127.0.0.1:30003 master - 0 1426238318243 3 connected 10923-16383 127.0.0.1:30001 myself,master - 0 0 1 connected 0-5460 我简化了上面的输出,但重要的部分是第一列中的主机地址和最后一个中的数字。5461-10922意味着这个节点处理开始于5461和结束于10922的插槽范围。 `MOVED`重定向 如果Redis群集中的某个节点接收到一个插槽不处理的的key的命令,则不会尝试向其他插槽转发该命令。相反,客户端会被告知在其他地方再次尝试。这是以MOVED新目标的地址作为回应的形式 : GET foo -MOVED 3999 127.0.0.1:6381 在集群重新平衡期间,插槽会从一个节点迁移到另一个节点,MOVED是服务器用于告诉客户端其插槽

01
领券