江南白衣--Clustering经典范文学习

本文详细解析了Java EE集群的核心概念、架构设计及关键组件,包括负载均衡、健康检查、会话复制等,旨在提供全面理解集群实现的指南。

[转载自]http://blog.youkuaiyun.com/calvinxiu/article/details/1602891

 

构造Cluster是架构师们实现ScalabilityHigh Availability 的最直接用药。所以大家很多都会无意中使用Cluster的思想去设计自己的服务器。其实Java EE里的Clustering已经做得很熟很烂,大家如果烂熟各家vendor对Web,EJB,JNDI,JMS,WebService....的Cluster实现,再思考自己的烂摊子时,思路便快捷清晰,少很多与同僚们的无谓争论。

     JavaEE Cluster的经典范文是Sun的王昱写于2005年的Uncover the hood of J2EE Clustering Preface,更可贵的是dev2dev上的JadeYuan兄弟将它高质的翻成了中文。 

 一、所谓集群  

          目的就是以负载均衡(Load Balance)与失败转移(Failover) 实现可扩展性(Scalability)和高可靠性(High Availability),主要实现的功能: 

Load Balance 算法主要有轮循、权重(根据服务器硬件配置的不同)和随机三种,但更酷的做法是基于负载(直接查探或者服务器主动报告它们的负载)。

Health Check心跳系统与发现协议。Server一般会主动定期多播报告自己状态,也会Ping对方来问候平安。比如Weblogic每10秒会向全世界发送一次心跳,如果有30秒没有收到某个服务器的心跳了(考虑到多播可能会丢失数据包)就可视对方为阵亡。

Session Replication 因为服务器会记录与特定用户的会话信息,Balancer应该把同一用户的请求定位到同一台服务器上。如果该服务器失效,就把该用户和会话信息转移到新服务器上。

除了Scalability 与High Availability,一个集群还应该对已有代码影响最小,对性能影响最小,配置与部署简单,以及运行时可监控。

 二、Web层群集 

    Balancer无非Apache/IIS插件,balance Servlet,硬件四层交换机三类,而讨论的重点在Session 信息的Replication 实现上,简单的分有全部服务器冗余备份,三三两两互为冗余备份,中央备份服务器三种模式。

              1.多服务器全冗余备份
              Tomcat的最为粗糙,最没有扩展性的做法,不提。Sun的怪怪的replacate的内存数据库法HADB可能也属于这种范畴。

              2.三三两两互为冗余备份
              Weblogic, Jboss and WebSphere 的做法,好主流。A会有B的数据,B会有C的数据,C会有B的数据,如果A出错,就会由C接替A的工作。这种做法的弊端是:
              1.要控制failover到备份服务器,Balancer的实现复杂度高。
              2.如果A出错,C就要瞬时承载A、C的操作,很可能将它压垮,针对这点,Weblogic的做法是针对每个session而不是每个Server选择备份服务器,把主备服务器A、B的名字写在用户Cookie里,如果A失效后,Balancer会根据cookie将用户转到服务器B。
              3.相对没有cluster的方案,需要花额外的时间和内存。

              文中没讲的Geronimo使用的WADI,应该也属于这种类型,不过更为灵活,详见Geronimo 叛逆者: 加入集群功能第1部分 和 第2部分。

              3. 中央备份服务器
              N+1模式,一个中央Server存放所有的Session,如果一台Server死了,接管的Server就从中央服务器restore相关数据。可以用数据库(很多应用服务器都支持的最简单,但最慢的模式),也可以采用内存。这种方式好处是cluster服务器上不需要冗余内存,可以failover到任意服务器,cluster服务器全死了中央服务器都不死。坏处就是如果中央服务器死了...如果中央服务器的内存不够了.....另外,多了个restore的步骤。

        使用内存备份session时,Tomcat/JBoss使用的JavaGroups 是一个很好的工具,它的" Group membership protocols" and "message multicast"特性都非常有用。

        另外,无论使用内存还是数据库,都需要串行化Java对象,性能损耗厉害,所以JRun 就采用了Jini架构 ,而Tangosol Coherenc ,Terracotta这些Data Grid方案都提出了自己的session备份做法,整天显示着比传统方案快多少多少。Data Grid分布式缓存本身就是很Enterprise的功能,下篇blog再详述。 

三、EJB集群

从stub 调用实际EJB对象时,有三种方法实现负载均衡和fail over:

  1. Smart Stub.在stub内维护有效列表,实现负载均衡逻辑,进行实效检测,BEA Weblogic and JBoss 采用。
  2. IIOP Runtime Library ,Sun的JES 算法,把算法从客户端的stub移到客户端的IIOP Runtime
  3. Interceptor Proxy,IBM做法,把算法移到了服务端,Location Service Daemon (LSD)。

在JNDI查找EJBHome,EJBHome Stub查找生成EJB实例,调用EJB方法三种时候都可以实现负载均衡,对statefull,stateless,entity bean,又有不同的做法。

EJB需要具有幂等性(在部署描述符中声明)才能failover。

四、其他集群

JMS集群,可以有多个broker组成集群(JBoss,如果要持久化Message,就要把原来嵌入式的数据库改为共享模式),activeMQ还支持多个消费者组成集群,但每个消费者负责同一类的任务,比如订单队列的处理,Server A只处理图书类的订单,或只处理《Programming Ruby 2nd》的订单。

数据库集群有Oracle的RAC,但JDBC本身的failover能力很低,一旦connection 中断,resultset等对象都会失效,Weblogic的连接池会尝试重连。

五、走的更远

   Weblogic9/10的广域网群集和服务器迁移(有些服务在群集中只能有一个实例在运行,如果该实例失效,迁移到下一个实例)功能。

    如果只要单纯的load balance,不要fail over的话,使用纯硬件如F5已经足够,不需要在软件上做任何事情。

   群集有两种模式,一种是只在入口的Web层进行负载均衡,一种是Web层和对象层(EJB)分别进行负载均衡。

六、Cluster的神话

1.Failover可彻底避免错误
   JBoss的文档用了整整一章来警告你,真的需要http session复制吗?没有http session可以使效率提高很多,而有了的话,并不能避免所有错误。失败转移只能在两次调用间产生作用,在调用时产生的错误是无法恢复的,除非这是个幂等操作(如单纯的get(),而不是put(),无论如何重复操作结果都是一样的),否则,如果A上承载100用户,失败时有20个用户正在进行处理,则只有80个用户能逃出生天平安转移到B。

2.小心编写可集群的程序

1.http session要放能serilaze的对象,对象不要太大,变更时要显式的setAttribute().

2. 注意Cache的使用。如果每个JVM独立使用Cache,会否不一致,如果进行同步,注意开销。

3.不能使用静态变量,如在线用户数,要搞成分布式的 Cache。

4.外部资源如文件系统(一台机器上没有另外一台机器的文件),存成DB或者使用SAN

5.特别服务:如timer服务,基于事件的服务

### 使用Transformer模型进行图像分类的方法 #### 方法概述 为了使Transformer能够应用于图像分类任务,一种有效的方式是将图像分割成固定大小的小块(patches),这些小块被线性映射为向量,并加上位置编码以保留空间信息[^2]。 #### 数据预处理 在准备输入数据的过程中,原始图片会被切分成多个不重叠的patch。假设一张尺寸为\(H \times W\)的RGB图像是要处理的对象,则可以按照设定好的宽度和高度参数来划分该图像。例如,对于分辨率为\(224\times 224\)像素的图像,如果选择每边切成16个部分的话,那么最终会得到\((224/16)^2=196\)个小方格作为单独的特征表示单元。之后,每一个这样的补丁都会通过一个简单的全连接层转换成为维度固定的嵌入向量。 ```python import torch from torchvision import transforms def preprocess_image(image_path, patch_size=16): transform = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), # 假设目标分辨率是224x224 transforms.ToTensor(), ]) image = Image.open(image_path).convert('RGB') tensor = transform(image) patches = [] for i in range(tensor.shape[-2] // patch_size): # 高度方向上的循环 row_patches = [] for j in range(tensor.shape[-1] // patch_size): # 宽度方向上的循环 patch = tensor[:, :, i*patch_size:(i+1)*patch_size, j*patch_size:(j+1)*patch_size].flatten() row_patches.append(patch) patches.extend(row_patches) return torch.stack(patches) ``` #### 构建Transformer架构 构建Vision Transformer (ViT),通常包括以下几个组成部分: - **Patch Embedding Layer**: 将每个图像块转化为低维向量; - **Positional Encoding Layer**: 添加绝对或相对位置信息给上述获得的向量序列; - **Multiple Layers of Self-Attention and Feed Forward Networks**: 多层自注意机制与前馈神经网络交替堆叠而成的核心模块; 最后,在顶层附加一个全局平均池化层(Global Average Pooling)以及一个多类别Softmax回归器用于预测类标签。 ```python class VisionTransformer(nn.Module): def __init__(self, num_classes=1000, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4., qkv_bias=False, drop_rate=0.): super().__init__() self.patch_embed = PatchEmbed(embed_dim=embed_dim) self.pos_embed = nn.Parameter(torch.zeros(1, self.patch_embed.num_patches + 1, embed_dim)) self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim)) dpr = [drop_rate for _ in range(depth)] self.blocks = nn.Sequential(*[ Block( dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, drop=dpr[i], ) for i in range(depth)]) self.norm = nn.LayerNorm(embed_dim) self.head = nn.Linear(embed_dim, num_classes) def forward(self, x): B = x.shape[0] cls_tokens = self.cls_token.expand(B, -1, -1) x = self.patch_embed(x) x = torch.cat((cls_tokens, x), dim=1) x += self.pos_embed x = self.blocks(x) x = self.norm(x) return self.head(x[:, 0]) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值