Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1315796
  • 博文数量: 554
  • 博客积分: 10425
  • 博客等级: 上将
  • 技术积分: 7555
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-09 09:49
文章分类

全部博文(554)

文章存档

2012年(1)

2011年(1)

2009年(8)

2008年(544)

分类:

2008-04-08 17:15:55

 

TIBCO Rendezvous 广泛应用于行业的关键任务性的和实时的消息传送中。典型情况下,使用 Rendezvous 的应用程序对性能和可靠性的要求会非常苛刻,因此可能给底层操作系统和硬件平台造成很大压力。这就有必要对系统进行调整,使其在最苛刻的环境中最大程度提高性能和可用性。

本文档解释了在 Solaris Operating System(OS)上运行 TIBCO Rendezvous 的最佳实践。像往常一样,随着更新和更好版本的应用程序、操作系统和硬件的推出,今天所推荐的最佳实践可能比它们的有用性的寿命更长。因此,有必要理解设置特殊参数的内在原理。本文档的第二部分将解释 Solaris OS 的内部工作方式,这会帮助用户理解特定参数的重要性,并对其使用作出更明智的决策。

Rendezvous 是一个实时的面向消息的中间件应用程序。在 Solaris OS 中,实时线程的优先度比任何系统或分时线程都要高,而且实时线程还在 CPU 上的处理调度上取得优先权。为了达到最佳性能,重要的是实时应用程序能够获得足够的处理能力。性能表征和分析在运行 Rendezvous 的 Solaris 平台上进行,以提出了能够用于实现最佳性能的最佳实践建议。

请注意:所建议的参数调整假定底层操作系统是 Solaris 8 OS 或更新版本。

实现最小化 UDP 数据包丢失的最佳实践

Rendezvous 使用 UDP 协议来进行其消息传送。在特定条件下,当系统通过网络接收数据包时,UDP 数据包可能会被丢掉。数据包丢失可表现为多种方式,其中的一些对于用户可能不是很明显。在一些例子中,丢失 UDP 数据包是因为 UDP 缓存已满,或者数据包在网络接口卡(NIC)驱动程序处丢失。下面的参数调整有助于最大程度减少 Solaris OS 平台上的数据包丢失。

    1. 创建一个处理器集并禁止其上的中断

    在 Solaris OS 中,中断具有最高的调度优先权(比实时线程高)。这样可确保了高优先权的系统事件能够立即以确定的方式被处理。中断有多种来源:一些是当数据包在网络上到达时 NIC 驱动程序引发的网络中断,一些是用于读写磁盘的磁盘中断。如果中断发生在运行着接收线程的 UDP 数据包的 CPU 上,它将中断 UDP 接收器线程。如果这种情况发生得太频繁,将会导致 UDP 接收器线程获得的 CPU 资源少于其处理数据包所需的资源。拥有较少的处理能力意味着底层的 UDP 缓存将会被填满,因为数据包无法被足够快地取出,最终导致数据包丢失。

    如何防止由于中断实时线程引起的中断

    为 Rendezvous Daemon 创建一个专用处理器集

    创建一个具有两个 CPU 的处理器集,将 Rendezvous daemon 进程与该处理器集绑定。另外,禁止该处理器集中的 CPU 上的中断,从而不会有中断发生在该处理器集中的处理器上。然而要注意的是,为一个过程创建一个处理器集则意味着其他进程不能在这些处理器上运行。

    简单来说,如果 Rendezvous daemon 不使用处理器集中的处理器,这些 CPU 的能力就无法用于任何其他进程。这可能在衡量系统大小来最大程度提高可用的 CPU 能力时造成障碍。另外,这种方法只适用于当系统中有两个以上可用 CPU 时或至少有两个 CPU 能够专用于处理器集时。例如,对于一个拥有两个以上联机 CPU 的机器。

      a. 获得可用的 CPU ID(只有处于 on-lineno-intr 状态的 CPU 可用于创建处理器集)。
      # psrinfo
      
      b. 创建一个拥有两个 CPU 的处理器集(来自可用的 CPU)。

      # psrset -c 给出所创建的处理器集的 ID。

      c. 在该处理器集上禁止中断:
      # psrset -f 
      
      d. 将 Rendezvous daemon processID 绑定到处理器集。
      # psrset -b   
      

    这将确保 Rendezvous daemon 获得一个具有两个 CPU 的专用处理器集,并且中断线程和 Rendezvous daemon 线程的处理不在同一个 CPU 上调度。

    2. 设备驱动器调整参数

    如果创建一个处理器集不可能或不可行,那么我们可以最大程度减少中断对调度实时线程的影响。典型情况下,一个运行消息传送应用程序的系统将在网络上接收很多的数据包。NIC 驱动程序将为服务网络上的数据包而引起一个中断。要调整设备驱动程序的可配置参数,可通过减少所生成的中断的数目以及调整驱动程序FIFO 来使更多的数据包在缓存中排队。

    3. 调整 GigaSwift Ethernet(Cassini)驱动程序的参数

    增加 FIFO 深度

    /etc/system 中,通过以下设置增加 FIFO 深度:

    set ce:ce_srv_fifo_depth=8192

    这将通过缓存更多的数据包来减少包丢失。

    中断合并

    增加中断计时器触发的超时设定。这将减少所生成的中断。

    # ndd -set /dev/ce rx_intr_time 30 

    这里,rx_intr_time 以系统时钟的 512 分之一为单位指定。

    4. 不要使用 /proc 工具和使用 /proc 工具的系统监测工具

    proc 工具,如 pmappfilespstack,在被检查时会停止进程。Rendezvous daemon 即使停止很短一段时间,也会导致较大的数据包丢失。

    建议:
    不要使用 proc 工具,如 pmappstack pfiles
    限制使用读取 /proc 文件的工具,例如 topprstat ps

    5. UDP 调整参数

    udp max 缓存大小增加到 1 Mbyte(缺省的 256 Kbyte 太小,特别是对于一个 Gigabit Ethernet 网络而言)。对于该操作的 ndd 调整参数是 udp_max_buf。将其设置为 1 Mbyte。

    # ndd -set /dev/udp  udp_max_buf  1048576
    

    6. fsflush 调整参数

    fsflush 是一个 Solaris OS Kernel daemon,它周期性扫描内存并将文件系统高速缓存中已修改的页面写到磁盘。在每次通过 fsflush daemon时,如果文件系统高速缓存中有大量的“脏”页面,那么在将页面写到磁盘时 fsflush 将会引起磁盘活动增加。这将导致磁盘中断增加,从而可能中断 UDP 接器线程。在这种情况下,最好减少由 fsflush daemon 的文件系统清理引起的干扰。

    /etc/system 文件中添加下列调整参数。

    set tune_t_fsflushr = 5 
    set autoup = 300
    

    tune_t_fsflushr 参数指定了 fsflush daemon “醒来”将已修改的页面写到磁盘的时间间隔。在这种情况下,fsflush daemon 将检查 tune_t_fsflushr/autoup(或 5/300)文件系统页面,并每隔 tune_t_fsflushr 秒将已修改的页面写到磁盘。

最大程度提高性能的最佳实践

    1. TCP 水印

    应用程序使用 TCP/IP 协议来向 Rendezvous daemon 发送数据以及从其接收数据。将 TCP 高或低水印设置为最优值值能够在 Rendezvous daemon 和应用程序之间实现较高的吞吐量(消息/秒)。使用这些参数获得的性能改进依赖于消息大小,而用户应尝试使用所推荐的这些值之一来实现最佳性能。对于发送大小不同的消息的应用程序,设置为 64 Kbyte 看来会较好。

    设置调整参数:

    # ndd -set /dev/tcp tcp_xmit_hiwat 65536
    # ndd -set /dev/tcp tcp_recv_hiwat 65536
    

    2. 禁止 UDP 校验和

    设置该调整参数将禁止在软件中禁止计算校验和,从而提高了传输性能。因为一些 NIC 在硬件中计算校验和,在软件中禁止校验和计算会帮助减少冗余。

    设置调整参数:

    # ndd -set /dev/udp udp_do_checksum 0
    

    3. tcp_maxpsz_multiplier

    当一个应用程序通过线路上发送数据包时,在其能够被发送前,存在着从用户到 kernel 缓存拷贝该数据包而引起的成本。该参数指定了应复制多少个最大数据段大小(MSS)的数据包。提高该参数将意味着我们进行较高的复制操作,每次操作要复制较多数据。

    # ndd -set /dev/tcp tcp_maxpsz_multiplier 10
    

Solaris OS 全局优先级模型

Solaris OS kernel 根据线程的全局优先级来调度它们(参见图 1)。当为 CPU 时间片调度线程时,高优先级线程优先于低优先级线程。这些线程被分配给不同的调度类,如时间共享(TS)、系统(SYS)和实时(RT)等。根据它们的优先级,这些线程在可用的 CPU 上调度。

图1:全局优先级(来源:Chien Yen)
图1:全局优先级(来源:Chien Yen)

什么是中断?

中断是外围设备用于通知 CPU 任务完成、错误条件和其他立即需要 CPU 处理的事件的机制。中断是异步产生的,并在中断上下文中处理。在 Solaris OS 中,中断线程具有最高优先级,比任何其他调度类中的线程都高(参见图 1)。例如,无论何时在网络上接收到数据包,NIC 都会产生中断。

中断如何影响 Rendezvous 性能?

当需要 CPU 即处理的事件发生时,中断就被产生了。因为中断具有比任何其他调度类都要高的调度优先级,所以,如果应用程序的实时线程在一个有许多中断的 CPU 上调度,那么实时线程将会被频繁中断。

当一个正在 CPU 上执行的线程被中断时,kernel 会避免上下文切换出被中断的线程。中断(作为线程运行)从正在执行的线程借用 LWP,而被中断的线程被认为是“钉”在 CPU 上。被中断的线程无法在其他任何处理器上运行,直到中断处理程序完成或在一个同步对象上阻塞。如果运行实时线程的 CPU 的中断负载较高,那么线程将会被频繁“钉住”(参阅参考部分的 Solaris 内幕)。另外,如果实时线程总是“可运行的”,那么调度器将不会把实时线程从“易于中断的” CPU 开到一个无法处理终端或空闲的 CPU。

所有这些因素合在一起,它们一起可能导致实时线程得到的 CPU 份额比合理的少,最终导致数据包丢失。

除了中断,Gigabit Ethernet 设备驱动在数据包到达网络接口后还有一种丢失数据包的可能。这些丢失不作为 udpInOverflows 统计出现,因此可能不被注意。首先,我们来了解从通过网络到达到它被传送给应用程序套接字这段时间内,数据包是如何传送的。

  1. 当数据包从网络上到达时,就产生中断。然后中断线程将中断当前在 CPU (也就是说被分配处理这个特定中断的CPU)上执行的线程。对于一些 Gigabit Ethernet Drivers (相对于 GigaSwift Ethernet Card),中断线程会将数据包放入一个 FIFO(对于拥有 4 个或更多 CPU 的系统)。
  2. 然后,设备驱动程序“工人线程”(在系统中运行,也就是,SYS 优先级类)从 FIFO 中获得数据包,将其“向上”传送到网络栈中的下一个模块(如图2所示)。
  3. UDP 接收器线程将数据包从套接字缓存中读出。
图2:数据包被如何处理
图2:如何处理数据包

注意:所有以上线程根据它们被调度的方式而可能运行在相同或不同的 CPU 上。前面的表假定它们竞争同一个 CPU 的一个时间片。

明白了如何处理数据包后,让我们仔细看一下可能导致数据包丢失的场景。

场景1:

设备驱动“工人线程”可能没有得到足够的 CPU 来讲数据包从 FIFO 中取出。同时,中断线程将继续从网络接收数据并将它们放入 FIFO。在这样一种场景中,FIFO 将变满,并表现为 GigaSwift Ethernet Ethernet Device 驱动程序的 kernel 统计数字(kstat)中 rx_pkts_dropped 统计数字的递增。这里的解决方案将增加 FIFO 深度,以便有更多的数据包能够在丢失前排队。

/etc/system 文件中,通过进行以下设置增加 FIFO 深度:

set ce:ce_srv_fifo_depth=8192

场景2:

如果中断发生在运行实时 UDP 接收器线程的 CPU 上,它们将会中断实时线程。如果这种情况发生得过于频繁,将会导致实时线程所获取的 CPU 时间片少于数据包处理所需的时间片。这将导致 UDP 缓存变满,并最终导致数据包丢失。为了减少网络中断的影响,我们能通过将设备驱动参数 rx_intr_time 设置为一个较高值来减少所产生的中断数目。

使用 ndd 设置该调整参数

# ndd -set /dev/ce rx_intr_time 30

注意:rx_intr_time 以系统时钟的 512 分之 1 为单位来指定。

小数据流量对性能的影响

应用程序发送的消息在网络上作为数据包传输。在线路上能够被传送的数据包的最大尺寸称为最大传输单位(MTU)。

不考虑网络带宽,CPU 占用限制了能够在线路上发送的数据包的数量。如下例所示,这在规划规模和容量时应被考虑。假定 MTU 为 1500 字节,另外假定用户 Mary 正在线路上发送一个 1500 字节的消息(包括 UDP/IP/Ethernet 头)。如果 Mary 能够发送以 10,000 个消息/秒的速度发送大小为 1500 字节的消息,她可能假设自己大概能够发送大小为1501(MTU+1)字节的同样一个消息。然而,由于消息大小现在超过了 MTU 大小,该消息(大小为 1501)将在网络上被分成两个数据包。这将导致这种大小消息的吞吐量与符合 MTU 大小的数据包的消息相比显著降低。

升级到 Gigabit 网络

除非应用程序性能在低网络带宽的情况下无法接受,否则应避免升级到 Gigabit Ethernet。在 Gigabit Ethernet 网络的情况下,要确保消息流量不会太“突发”。下面是一个帮助说明这个问题的例子:发送 100 Mbytes 数据的应用程序在千兆网络上以 0.1 秒这样的“突发”时间完成传送,而在 100 Mbit/秒的网络上需持续 1 秒。对于千兆网络,传输率是 1 Gbyte/秒,对于 100BaseT 网络,传输率是 100 Mbit/秒。然而,如果对 1 秒的时间段进行“平均”,两种情况下传输率都是 100 Mbit/秒。如果千兆网络上的接收者不能处理数据的突发传输(以 1 Gbit/秒),那么接收者可能会丢失数据包;而 100BaseT 网络上的接收者则可能能够处理流量。

其他因素

像容量和缓存等因素对于处理数据包的交换机和路由器也扮演着重要的角色。对于 IP 多播流量更是这样——不是所有的交换机和路由器都拥有有效处理大流量 IP 多播流量的能力。

  1. ,James Mauro and Richard McDougall
  2. Solaris Processor Sets Made Easy,Dr. Matthias Laux

感谢 Sun Microsystems 的 Performance and Availability Engineering group 的 Bob Sneed、Roch Bourbonnais 和 Paul Riethmuller,感谢他们对调整参数所给予的分析和建议。也感谢 Chien Yen 提供全局优先级的图表。

Amol Khire 是一个 Sun Microsystems 工程师,他和独立软件开发商(ISV)一起工作来提高其应用程序在 Sun 平台上的性能、可扩展性和可用性。他的兴趣包括实时消息传送、RFID 和企业应用程序集成(EAI)技术。

 

以上文章转自于 :

 

阅读(836) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~