RDMA 使用小总结

本文是将原先发于知乎的琐碎文章进行整理总结。

RDMA 性能优化

Tips and trick to optimize your RDMA code 笔记

Tips and trick to optimize your RDMA code 笔记

原文来源于 RDMAmojo,该文章涵盖了优化 RDMA 时延、吞吐、资源占用等几个方面的优化技巧,非常实用,基本都能在日常开发中用得上。

还有其他 RDMA 相关的优化手段么?

优化 RDMA 收发包的大小,尽量减少包的大小,消除冗余信息的传输。

然而。。

然而单纯从 RDMA 使用角度优化代码是有极限的:RDMA 本身是微秒级速度的程序。如果程序本身有其他影响性能的因素,会产生毫秒或者秒级别的性能劣化,那再怎么优化 RDMA 的使用也无力挽回大局。

除非将程序本身的优化也一并考虑在内,全方位地考虑将所有优化手段一并考虑在内,这样才能超越极限!

RDMA read 和 write 的使用思路上的区别

以 C/S 结构中,client 需要获取 server 的数据这一场景为例。
Read 操作是最直观的,client 直接 read 回来 server 侧指定位置的数据。如果 Server 侧数据是分开存储的情况下,Client 可能需要多次 read 操作。
Write 操作则是 client 往 server 发送了一个请求后,server 通过 write 来将数据写到 client 侧指定位置。好处是 server 知道自己的数据在哪,因此只需要一次 write。但是 client 需要能够感知到数据被写过来了,这就需要通过比如 client 定期轮询 buffer,通过标识位来判断是否有新数据被写入,server 已经把数据传完。或者通过 write_imm 中的立即数来通知。
总的来说,两者起码都是需要 1 rtt,read 可能比 write 多几个 rtt。write 相比 read 来说,需要 server 侧介入。两者是一个 server 侧 cpu 负载和时延/吞吐之间的权衡。

RDMA write 的写入顺序

对于 RDMA write 来说,RDMA 和 IB 规格书上没写写入的顺序一定是按照顺序来写入的,但大部分厂商的实现方式是顺序写入。所以当接收方读到写入的最后一位时,就基本可以认为数据已经传输完成了。

RDMA send/recv 之思

消息语义(send/recv)需要提前准备好一定数量的 recv。并且在运行过程中还需要持续不断地补充新的 recv,比如收到一个 send 就补充一个 recv。Send 的速率不同,需要提前准备的 recv 数量就不同,不然就可能存在 send 超时导致的失败。
结合许多论文中所说的,用 write 的效果会更好来看,RDMA 真正的用法应该是 READ/WRITE 这种单边语义,思考怎么用的时候应该尽量往这方面去靠,才能最大地发挥出 RDMA 的特色。
SEND/RECV 的用法,能想到的,是需要简单的设计一下的时候,因为消息语义用法较简单,平替 SOCKET 比较容易。内存语义在设计的时候就要考虑更多,设计起来更难。

如何实现一个简单的 HashMap

HashMap 是个 LinkedList<HashMapEntry<K, V>>[], 或 TreeNode<HashMapEntry<K, V>>[]

1. 实现 HashMapEntry

  • 顺便重写下 equal 和 hashcode

2. 实现 HashMap 的方法

  • hash():计算hash
  • get():在相应的 table[hash(key)] 中寻找相应的值
  • put(): 考虑要不要 resize
  • resize(): 扩充 hashmap
  • remove()
  • 其他可选方法,如 clone,replace 等

3. 考虑并行操作异常

  • 在增删改方法添加 modCount 计数,抛出 ConcurrentModificationException 异常

4. 考虑遍历:EntrySet

  • 先实现 Iterator 类

    • 实现 hasNext,next
  • 实现 EntrySet 类

    • iterator()
    • contain()
    • remove()

5. 考虑树化

  • 在 put 和 remove 中添加符合树化条件的情况,和从树转换回链表的情况
  • 实现 TreeNode 类 (具体实现再议)
访问量: 访客数: