﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-The important thing in life is to have a great aim , and the determination -随笔分类-IT技术相关</title><link>http://www.blogjava.net/tjyhy590/category/21576.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 20 Apr 2020 23:33:59 GMT</lastBuildDate><pubDate>Mon, 20 Apr 2020 23:33:59 GMT</pubDate><ttl>60</ttl><item><title>POI操作Excel</title><link>http://www.blogjava.net/tjyhy590/archive/2020/03/20/435285.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Fri, 20 Mar 2020 02:13:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2020/03/20/435285.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/435285.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2020/03/20/435285.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/435285.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/435285.html</trackback:ping><description><![CDATA[一、POI概述

　　Apache POI是Apache软件基金会的开放源码函式库，POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

　　结构：
     HSSF － 提供读写Microsoft Excel格式档案的功能。
     XSSF － 提供读写Microsoft Excel OOXML格式档案的功能。
     HWPF － 提供读写Microsoft Word格式档案的功能。
     HSLF － 提供读写Microsoft PowerPoint格式档案的功能。
     HDGF － 提供读写Microsoft Visio格式档案的功能。

　使用必须引入依赖

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>
注：3.17版本是支持jdk6的最后版本

二、HSSF概况

　　HSSF 是Horrible SpreadSheet Format的缩写，通过HSSF，你可以用纯Java代码来读取、写入、修改Excel文件。HSSF 为读取操作提供了两类API：usermodel和eventusermodel，即&#8220;用户模型&#8221;和&#8220;事件-用户模型&#8221;。

三、 POI EXCEL文档结构类

   HSSFWorkbook excel文档对象
   HSSFSheet excel的sheet
   HSSFRow excel的行
   HSSFCell excel的单元格
HSSFFont excel字体
HSSFName 名称
HSSFDataFormat 日期格式
HSSFHeader sheet头
HSSFFooter sheet尾
HSSFCellStyle cell样式
HSSFDateUtil 日期
HSSFPrintSetup 打印
HSSFErrorConstants 错误信息表
四、EXCEL的读写操作

1、读取&#8220;区域数据.xls&#8221;并储存于list集合中，&#8220;区域数据.xls&#8221;如下图




 public List<Area> importXLS(){
  
      ArrayList<Area> list = new ArrayList<>();
      try {
  　　　　　//1、获取文件输入流
  　　　　　InputStream inputStream = new FileInputStream("/Users/Shared/区域数据.xls");
  　　　　　//2、获取Excel工作簿对象
          HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
  　　　　　//3、得到Excel工作表对象
         HSSFSheet sheetAt = workbook.getSheetAt(0);
         //4、循环读取表格数据
 　　　　 for (Row row : sheetAt) {
 　　　　　　　//首行（即表头）不读取
             if (row.getRowNum() == 0) {
                 continue;
             }
             //读取当前行中单元格数据，索引从0开始
 　　　　　　　String areaNum = row.getCell(0).getStringCellValue(); 
             String province = row.getCell(1).getStringCellValue();
             String city = row.getCell(2).getStringCellValue();
             String district = row.getCell(3).getStringCellValue();
             String postcode = row.getCell(4).getStringCellValue();
              Area area = new Area();
             area.setCity(city);
             area.setDistrict(district);
             area.setProvince(province);
 　　　　　　　area.setPostCode(postcode);
             list.add(area);
         }
 　　　　 //5、关闭流
         workbook.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
 　　return list;
 }

2、导出数据到&#8220;区域数据.xls&#8221;文件中，页面数据如下图：




  public void exportExcel() throws IOException {
  
          Page<Area> page = areaService.pageQuery(null);
          List<Area> list = page.getContent();
  
          //1.在内存中创建一个excel文件
          HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
          //2.创建工作簿
          HSSFSheet sheet = hssfWorkbook.createSheet();
         //3.创建标题行
         HSSFRow titlerRow = sheet.createRow(0);
         titlerRow.createCell(0).setCellValue("省");
         titlerRow.createCell(1).setCellValue("市");
         titlerRow.createCell(2).setCellValue("区");
         titlerRow.createCell(3).setCellValue("邮编");
         titlerRow.createCell(4).setCellValue("简码");
         titlerRow.createCell(5).setCellValue("城市编码");
 
         //4.遍历数据,创建数据行
         for (Area area : list) {
             //获取最后一行的行号
             int lastRowNum = sheet.getLastRowNum();
             HSSFRow dataRow = sheet.createRow(lastRowNum + 1);
             dataRow.createCell(0).setCellValue(area.getProvince());
             dataRow.createCell(1).setCellValue(area.getCity());
             dataRow.createCell(2).setCellValue(area.getDistrict());
             dataRow.createCell(3).setCellValue(area.getPostcode());
             dataRow.createCell(4).setCellValue(area.getShortcode());
             dataRow.createCell(5).setCellValue(area.getCitycode());
         }
         //5.创建文件名
         String fileName = "区域数据统计.xls";
         //6.获取输出流对象
         HttpServletResponse response = ServletActionContext.getResponse();
         ServletOutputStream outputStream = response.getOutputStream();
 
         //7.获取mimeType
         ServletContext servletContext = ServletActionContext.getServletContext();
         String mimeType = servletContext.getMimeType(fileName);
         //8.获取浏览器信息,对文件名进行重新编码
         HttpServletRequest request = ServletActionContext.getRequest();
         fileName = FileUtils.filenameEncoding(fileName, request);
 
         //9.设置信息头
         response.setContentType(mimeType);
         response.setHeader("Content-Disposition","attachment;filename="+fileName);
         //10.写出文件,关闭流
         hssfWorkbook.write(outputStream);
         hssfWorkbook.close();
     }

工具类


  public class FileUtils {
  
      public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
          String agent = request.getHeader("User-Agent"); //获取浏览器
          if (agent.contains("Firefox")) {
              BASE64Encoder base64Encoder = new BASE64Encoder();
              filename = "=?utf-8?B?"
                      + base64Encoder.encode(filename.getBytes("utf-8"))
                      + "?=";
         } else if(agent.contains("MSIE")) {
             filename = URLEncoder.encode(filename, "utf-8");
         } else if(agent.contains ("Safari")) {
             filename = new String (filename.getBytes ("utf-8"),"ISO8859-1");
         } else {
             filename = URLEncoder.encode(filename, "utf-8");
         }
         return filename;
     }
 }

 写出xls文件：



五、 EXCEL常用操作方法

1、 得到Excel常用对象


 POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:/test.xls")); 
  //得到Excel工作簿对象 
  HSSFWorkbook wb = new HSSFWorkbook(fs); 
  //得到Excel工作表对象 
  HSSFSheet sheet = wb.getSheetAt(0); 
  //得到Excel工作表的行 
  HSSFRow row = sheet.getRow(i); 
  //得到Excel工作表指定行的单元格 
  HSSFCell cell = row.getCell((short) j); 
 cellStyle = cell.getCellStyle();//得到单元格样式

2、建立Excel常用对象


 HSSFWorkbook wb = new HSSFWorkbook();//创建Excel工作簿对象 
 HSSFSheet sheet = wb.createSheet("new sheet");//创建Excel工作表对象 
 HSSFRow row = sheet.createRow((short)0); //创建Excel工作表的行 
 cellStyle = wb.createCellStyle();//创建单元格样式 
 row.createCell((short)0).setCellStyle(cellStyle); //创建Excel工作表指定行的单元格 
 row.createCell((short)0).setCellValue(1); //设置Excel工作表的值

3、设置sheet名称和单元格内容

 wb.setSheetName(1, "第一张工作表",HSSFCell.ENCODING_UTF_16); 
 cell.setEncoding((short) 1); 
 cell.setCellValue("单元格内容");
4、取得sheet的数目

 wb.getNumberOfSheets()
5、 根据index取得sheet对象

 HSSFSheet sheet = wb.getSheetAt(0);
6、取得有效的行数

 int rowcount = sheet.getLastRowNum();
7、取得一行的有效单元格个数

 row.getLastCellNum();
8、单元格值类型读写

 cell.setCellType(HSSFCell.CELL_TYPE_STRING); //设置单元格为STRING类型 
 cell.getNumericCellValue();//读取为数值类型的单元格内容 
9、设置列宽、行高

 sheet.setColumnWidth((short)column,(short)width); 
 row.setHeight((short)height);
10、添加区域，合并单元格
 Region region = new Region((short)rowFrom,(short)columnFrom,(short)rowTo 
 ,(short)columnTo);//合并从第rowFrom行columnFrom列 
 sheet.addMergedRegion(region);// 到rowTo行columnTo的区域 
 //得到所有区域 
 sheet.getNumMergedRegions() 
11、保存Excel文件

 FileOutputStream fileOut = new FileOutputStream(path); 
 wb.write(fileOut);
12、根据单元格不同属性返回字符串数值

  public String getCellStringValue(HSSFCell cell) { 
  　　String cellValue = ""; 
  　　switch (cell.getCellType()) { 
  　　　　case HSSFCell.CELL_TYPE_STRING://字符串类型 
  　　　　　　　　cellValue = cell.getStringCellValue(); 
  　　　　　　　　if(cellValue.trim().equals("")||cellValue.trim().length()<=0) 
  　　　　　　　　　　cellValue=" "; 
  　　　　　　　　break; 
  　　　　case HSSFCell.CELL_TYPE_NUMERIC: //数值类型 
 　　　　　　　　cellValue = String.valueOf(cell.getNumericCellValue()); 
 　　　　　　　　break; 
 　　　　case HSSFCell.CELL_TYPE_FORMULA: //公式 
 　　　　　　　　cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); 
 　　　　　　　　cellValue = String.valueOf(cell.getNumericCellValue()); 
 　　　　　　　　break; 
 　　　　case HSSFCell.CELL_TYPE_BLANK: 
 　　　　　　　　cellValue=" "; 
 　　　　　　　　break; 
 　　　　case HSSFCell.CELL_TYPE_BOOLEAN: 
 　　　　　　　　break; 
 　　　　case HSSFCell.CELL_TYPE_ERROR: 
 　　　　　　　　break; 
 　　　　default: 
 　　　　　　　　break; 
 　　} 
 　　return cellValue; 
 }

13、常用单元格边框格式

 HSSFCellStyle style = wb.createCellStyle(); 
 style.setBorderBottom(HSSFCellStyle.BORDER_DOTTED);//下边框 
 style.setBorderLeft(HSSFCellStyle.BORDER_DOTTED);//左边框 
 style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框 
 style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
14、设置字体和内容位置
  HSSFFont f = wb.createFont(); 
  f.setFontHeightInPoints((short) 11);//字号 
  f.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);//加粗 
  style.setFont(f); 
  style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中 
  style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中 
  style.setRotation(short rotation);//单元格内容的旋转的角度 
  HSSFDataFormat df = wb.createDataFormat(); 
  style1.setDataFormat(df.getFormat("0.00%"));//设置单元格数据格式 
 cell.setCellFormula(string);//给单元格设公式 
 style.setRotation(short rotation);//单元格内容的旋转的角度

15、插入图片
  //先把读进来的图片放到一个ByteArrayOutputStream中，以便产生ByteArray 
  ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); 
  BufferedImage bufferImg = ImageIO.read(new File("ok.jpg")); 
  ImageIO.write(bufferImg,"jpg",byteArrayOut); 
  //读进一个excel模版 
  FileInputStream fos = new FileInputStream(filePathName+"/stencil.xlt"); 
  fs = new POIFSFileSystem(fos); 
  //创建一个工作薄 
  HSSFWorkbook wb = new HSSFWorkbook(fs); 
 HSSFSheet sheet = wb.getSheetAt(0); 
 HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); 
 HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)10,10); 
 patriarch.createPicture(anchor , wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));

16、调整工作表位置


 HSSFWorkbook wb = new HSSFWorkbook(); 
 HSSFSheet sheet = wb.createSheet("format sheet"); 
 HSSFPrintSetup ps = sheet.getPrintSetup(); 
 sheet.setAutobreaks(true); 
 ps.setFitHeight((short)1); 
 ps.setFitWidth((short)1);
  <img src ="http://www.blogjava.net/tjyhy590/aggbug/435285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2020-03-20 10:13 <a href="http://www.blogjava.net/tjyhy590/archive/2020/03/20/435285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>python操作文件存在的问题解决办法</title><link>http://www.blogjava.net/tjyhy590/archive/2019/05/14/433783.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Tue, 14 May 2019 15:04:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2019/05/14/433783.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/433783.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2019/05/14/433783.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/433783.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/433783.html</trackback:ping><description><![CDATA[ 1、在学习从文件读取数据中，写了个示例代码，读取不在同一个目录的file.txt，运行后报这个Python OSError: [Errno 22] Invalid argument:错误：

（1）、首先，在F盘的python_stu中新增了一个file.txt，同时在F盘的python_stu文件目录底下新增一个file文件夹，里面有个file_reader.py来读取python_stu文件目录底下的file.txt，代码分别如下：

file.txt：

测试
测试2
测试3

file_reader.py：

with open('F:\python_stu\file.txt') as file_obj:
    contents = file_obj.read();
    print(contents.rstrip());
（2）、运行后报错：



（3）、出现这种错误的原因是由于读取不到这个文件，看Traceback报的错误，最后一行，很明显读取不到file.txt，前面的F:\\python_stu没错，后面的名称怎么变了，还是x0cile.txt。

（4）、解决办法，可修改上述第一行代码为：

with open('F:\python_stu/file.txt') as file_obj:
或者：

with open('F:/python_stu/file.txt') as file_obj:
或者：

with open('F://python_stu//file.txt') as file_obj:
又或者：

with open('F:\\python_stu\\file.txt') as file_obj:
还有一些我就不附上了，上面第一种方式不统一，最好不要用，用统一的方式，而且有时候还有注意一些转义字符，比如 \t，\n也会导致报错。
<img src ="http://www.blogjava.net/tjyhy590/aggbug/433783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2019-05-14 23:04 <a href="http://www.blogjava.net/tjyhy590/archive/2019/05/14/433783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hadoop-2.4.1学习之QJM HA的自动故障转移</title><link>http://www.blogjava.net/tjyhy590/archive/2017/08/13/432740.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Sun, 13 Aug 2017 10:49:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/08/13/432740.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432740.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/08/13/432740.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432740.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432740.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">前面学习了使用命令hdfs haadmin -failover手动进行故障转移，在该模式下，即使现役NameNode已经失效，系统也不会自动从现役NameNode转移到待机NameNode，下面学习如何配置部署HA自动进行故障转移。自动故障转移为HDFS部署增加了两个新组件：ZooKeeper和ZKFailoverController（ZKFC）进程。ZooKeeper是维护少量协调数据，通知客户端这些数据的改变和监视客户端故障的高可用服务。HA的自动故障转移依赖于ZooKeeper的以下功能：</p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><ul style="font-family: Arial; background-color: #ffffff;"><li>故障检测：集群中的每个NameNode在ZooKeeper中维护了一个持久会话，如果机器崩溃，ZooKeeper中的会话将终止，ZooKeeper通知另一个NameNode需要触发故障转移。</li><li>现役NameNode选择：ZooKeeper提供了一个简单的机制用于唯一的选择一个节点为active状态。如果目前现役NameNode崩溃，另一个节点可能从ZooKeeper获得特殊的排外锁以表明它应该成为现役NameNode。</li></ul><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;ZKFC是自动故障转移中的另一个新组件，是ZooKeeper的客户端，也监视和管理NameNode的状态。每个运行NameNode的主机也运行了一个ZKFC进程，ZKFC负责：</p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><ul style="font-family: Arial; background-color: #ffffff;"><li>健康监测：ZKFC使用一个健康检查命令定期地ping与之在相同主机的NameNode，只要该NameNode及时地回复健康状态，ZKFC认为该节点是健康的。如果该节点崩溃，冻结或进入不健康状态，健康监测器标识该节点为非健康的。</li><li>ZooKeeper会话管理：当本地NameNode是健康的，ZKFC保持一个在ZooKeeper中打开的会话。如果本地NameNode处于active状态，ZKFC也保持一个特殊的znode锁，该锁使用了ZooKeeper对短暂节点的支持，如果会话终止，锁节点将自动删除。</li><li>基于ZooKeeper的选择：如果本地NameNode是健康的，且ZKFC发现没有其它的节点当前持有znode锁，它将为自己获取该锁。如果成功，则它已经赢得了选择，并负责运行故障转移进程以使它的本地NameNode为active。故障转移进城与前面描述的手动故障转移相似，首先如果必要保护之前的现役NameNode，然后本地NameNode转换为active状态。</li></ul><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;在典型部署中，ZooKeeper守护进程运行在三个或者五个节点上，但由于ZooKeeper本身需要较少的资源，所以将ZooKeeper部署在与现役NameNode和待机NameNode相同的主机上，还可以将ZooKeeper部署到与YARN的ResourceManager相同的节点上。建议配置ZooKeeper将数据存储在与HDFS元数据不同的硬盘上以得到最好的性能和隔离性。在配置自动故障转移之前需要先停掉集群，目前在集群运行时还不可能将手动故障转移的安装转换为自动故障转移的安装。接下来看看如何配置HA的自动故障转移。首先在hdfs-site.xml中添加下面的参数，该参数的值默认为false：</p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><div bg_html"="" style="width: 936.531px; overflow-y: hidden; position: relative;"><div><div style="border-left-color: #999999;"><strong>[html]</strong>&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="view plain" target="_blank">view plain</a><span data-mod="popu_168">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="copy" target="_blank">copy</a><div style="position: absolute; left: 487px; top: 1010px; width: 27px; height: 15px; z-index: 99;"></div></span><span data-mod="popu_169">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="print" target="_blank">print</a></span><a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="?" target="_blank">?</a></div></div><ol start="1"><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;"><span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">property</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">name</span><span style="color: blue; font-weight: bold;">&gt;</span>dfs.ha.automatic-failover.enabled<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">name</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">value</span><span style="color: blue; font-weight: bold;">&gt;</span>true<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">value</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;"><span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">property</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li></ol></div><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;在core-site.xml文件中添加下面的参数，该参数的值为ZooKeeper服务器的地址，ZKFC将使用该地址。</p><div bg_html"="" style="width: 936.531px; overflow-y: hidden; position: relative;"><div><div style="border-left-color: #999999;"><strong>[html]</strong>&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="view plain" target="_blank">view plain</a><span data-mod="popu_168">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="copy" target="_blank">copy</a><div style="position: absolute; left: 487px; top: 1174px; width: 27px; height: 15px; z-index: 99;"></div></span><span data-mod="popu_169">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="print" target="_blank">print</a></span><a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="?" target="_blank">?</a></div></div><ol start="1"><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;"><span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">property</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">name</span><span style="color: blue; font-weight: bold;">&gt;</span>ha.zookeeper.quorum<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">name</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">value</span><span style="color: blue; font-weight: bold;">&gt;</span>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">value</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;"><span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">property</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li></ol></div><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;在HA或者HDFS联盟中，上面的两个参数还需要以NameServiceID为后缀，比如dfs.ha.automatic-failover.enabled.mycluster。除了上面的两个参数外，还有其它几个参数用于自动故障转移，比如ha.zookeeper.session-timeout.ms，但对于大多数安装来说都不是必须的。</p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;在添加了上述的配置参数后，下一步就是在ZooKeeper中初始化要求的状态，可以在任一NameNode中运行下面的命令实现该目的，该命令将在ZooKeeper中创建znode：</p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><div bg_java"="" style="width: 936.531px; overflow-y: hidden; position: relative;"><div><div style="border-left-color: #999999;"><strong>[java]</strong>&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="view plain" target="_blank">view plain</a><span data-mod="popu_168">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="copy" target="_blank">copy</a><div style="position: absolute; left: 485px; top: 1398px; width: 27px; height: 15px; z-index: 99;"></div></span><span data-mod="popu_169">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="print" target="_blank">print</a></span><a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="?" target="_blank">?</a></div></div><ol start="1"><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">$&nbsp;hdfs&nbsp;zkfc&nbsp;-formatZK&nbsp;&nbsp;</li></ol></div><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;在启用自动故障转移的集群中，start-dfs.sh脚本将在任何运行NameNode的主机上自动启动ZKFC守护进程，一旦ZKFC启动完毕，它们将自动选择一个NameNode为现役NameNode。如果手动管理集群中的服务，需要在每台运行NameNode的主机上手动启动ZKFC，命令为：</p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><div bg_java"="" style="width: 936.531px; overflow-y: hidden; position: relative;"><div><div style="border-left-color: #999999;"><strong>[java]</strong>&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="view plain" target="_blank">view plain</a><span data-mod="popu_168">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="copy" target="_blank">copy</a><div style="position: absolute; left: 485px; top: 1534px; width: 27px; height: 15px; z-index: 99;"></div></span><span data-mod="popu_169">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="print" target="_blank">print</a></span><a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="?" target="_blank">?</a></div></div><ol start="1"><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">hadoop-daemon.sh&nbsp;start&nbsp;zkfc&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;">hdfs&nbsp;zkfc&nbsp;&nbsp;</li></ol></div><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;如果正在运行一个安全的集群，可能想确保存储在ZooKeeper中的信息也是安全的，这将阻止恶意的客户端修改ZooKeeper中的元数据或者潜在地触发一个错误的故障转移。为了保护ZooKeeper中的信息，首先在core-site.xml中添加下面的参数：</p><div bg_html"="" style="width: 936.531px; overflow-y: hidden; position: relative;"><div><div style="border-left-color: #999999;"><strong>[html]</strong>&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="view plain" target="_blank">view plain</a><span data-mod="popu_168">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="copy" target="_blank">copy</a><div style="position: absolute; left: 487px; top: 1688px; width: 27px; height: 15px; z-index: 99;"></div></span><span data-mod="popu_169">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="print" target="_blank">print</a></span><a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="?" target="_blank">?</a></div></div><ol start="1"><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;"><span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">property</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">name</span><span style="color: blue; font-weight: bold;">&gt;</span>ha.zookeeper.auth<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">name</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">value</span><span style="color: blue; font-weight: bold;">&gt;</span>@/path/to/zk-auth.txt<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">value</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;">&nbsp;<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">property</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">property</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">name</span><span style="color: blue; font-weight: bold;">&gt;</span>ha.zookeeper.acl<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">name</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: blue; font-weight: bold;">&lt;</span><span style="color: blue; font-weight: bold;">value</span><span style="color: blue; font-weight: bold;">&gt;</span>@/path/to/zk-acl.txt<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">value</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;">&nbsp;<span style="color: blue; font-weight: bold;">&lt;/</span><span style="color: blue; font-weight: bold;">property</span><span style="color: blue; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li></ol></div><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;参数值中的@字符表示参数值保存在@后的硬盘文件中。第一个配置文件指定了ZooKeeper的认证列表，其格式与ZK CLI使用的相同，例如：digest:hdfs-zkfcs:mypassword，其中hdfs-zkfcs为ZooKeeper的用户名，mypassword为密码。其次使用下面的命令为该认证生成一个ZooKeeper访问控制列表：</p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><div bg_java"="" style="width: 936.531px; overflow-y: hidden; position: relative;"><div><div style="border-left-color: #999999;"><strong>[java]</strong>&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="view plain" target="_blank">view plain</a><span data-mod="popu_168">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="copy" target="_blank">copy</a><div style="position: absolute; left: 485px; top: 1976px; width: 27px; height: 15px; z-index: 99;"></div></span><span data-mod="popu_169">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="print" target="_blank">print</a></span><a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="?" target="_blank">?</a></div></div><ol start="1"><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">$&nbsp;java&nbsp;-cp&nbsp;$ZK_HOME/lib/*:$ZK_HOME/zookeeper-<span style="color: #c00000;">3.4</span>.<span style="color: #c00000;">2</span>.jar&nbsp;org.apache.zookeeper.server.auth.DigestAuthenticationProvider&nbsp;hdfs-zkfcs:mypassword&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;">output:&nbsp;hdfs-zkfcs:mypassword-&gt;hdfs-zkfcs:P/OQvnYyU/nF/mGYvB/xurX8dYs=&nbsp;&nbsp;&nbsp;</li></ol></div><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;拷贝-&gt;之后的字符串并添加digest:前缀，然后粘贴到zk-acls.txt中，例如：digest:hdfs-zkfcs:vlUvLnd8MlacsE80rDuu6ONESbM=:rwcda。要想使ACLs生效，需要再次运行zkfc &#8211;formatZK。最后可能像下面这样在ZK CLI中验证ACLs：</p><div bg_java"="" style="width: 936.531px; overflow-y: hidden; position: relative;"><div><div style="border-left-color: #999999;"><strong>[java]</strong>&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="view plain" target="_blank">view plain</a><span data-mod="popu_168">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="copy" target="_blank">copy</a><div style="position: absolute; left: 485px; top: 2148px; width: 27px; height: 15px; z-index: 99;"></div></span><span data-mod="popu_169">&nbsp;<a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="print" target="_blank">print</a></span><a href="http://blog.csdn.net/skywalker_only/article/details/40300839#" title="?" target="_blank">?</a></div></div><ol start="1"><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">[zk:&nbsp;localhost:<span style="color: #c00000;">2181</span>(CONNECTED)&nbsp;<span style="color: #c00000;">1</span>]&nbsp;getAcl&nbsp;/hadoop-ha&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; color: #555555; line-height: 18px;"><span style="color: red;">'digest,'</span>hdfs-zkfcs:vlUvLnd8MlacsE80rDuu6ONESbM=&nbsp;&nbsp;</li><li style="border-left-color: #999999; background-color: #f5fae2; line-height: 18px;">:&nbsp;cdrwa&nbsp;&nbsp;</li></ol></div><p style="margin: 0px; padding: 0px; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;在安装完成自动故障转移后，或许需要<a href="http://lib.csdn.net/base/softwaretest" title="软件测试知识库" target="_blank" style="color: #df3434; text-decoration: none; font-weight: bold;">测试</a>一下。首先定位现役NameNode，可以通过访问NameNode的web页面来确定哪个NameNode是active状态的。一旦确定了处于active状态的NameNode，就需要在该节点上制造点故障，比如使用命令kill -9 &lt;pid of NN&gt;模拟JVM崩溃，或重启主机或拔掉网线来模拟不同的中断。一旦触发了自动故障转移，另一个NameNode应该自动在几秒钟内变为active状态。检测到故障并触发故障转移由参数ha.zookeeper.session-timeout.ms控制，该参数为与core-site.xml中，默认为5秒。如果测试不成功，可能是配置问题，检查ZKFC和NameNode进程的日志以进一步诊断问题，通常错误都是很明显的。</p><img src ="http://www.blogjava.net/tjyhy590/aggbug/432740.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-08-13 18:49 <a href="http://www.blogjava.net/tjyhy590/archive/2017/08/13/432740.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Yarn 调度器Scheduler详解</title><link>http://www.blogjava.net/tjyhy590/archive/2017/08/05/432722.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Fri, 04 Aug 2017 16:35:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/08/05/432722.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432722.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/08/05/432722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432722.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432722.html</trackback:ping><description><![CDATA[<p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">理想情况下，我们应用对Yarn资源的请求应该立刻得到满足，但现实情况资源往往是有限的，特别是在一个很繁忙的集群，一个应用资源的请求经常需要等待一段时间才能的到相应的资源。在Yarn中，负责给应用分配资源的就是Scheduler。其实调度本身就是一个难题，很难找到一个完美的策略可以解决所有的应用场景。为此，Yarn提供了多种调度器和可配置的策略供我们选择。</p><h2>一、调度器的选择</h2><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">在Yarn中有三种调度器可以选择：<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">FIFO Scheduler</code>&nbsp;，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">Capacity Scheduler</code>，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">FairS cheduler</code>。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;"><code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">FIFO Scheduler</code>把应用按提交的顺序排成一个队列，这是一个先进先出队列，在进行资源分配的时候，先给队列中最头上的应用进行分配资源，待最头上的应用需求满足后再给下一个分配，以此类推。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;"><code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">FIFO Scheduler</code>是最简单也是最容易理解的调度器，也不需要任何配置，但它并不适用于共享集群。大的应用可能会占用所有集群资源，这就导致其它应用被阻塞。在共享集群中，更适合采用<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">Capacity Scheduler</code>或<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">Fair Scheduler</code>，这两个调度器都允许大任务和小任务在提交的同时获得一定的系统资源。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">下面<em style="padding: 0px;">&#8220;Yarn调度器对比图&#8221;</em>展示了这几个调度器的区别，从图中可以看出，在FIFO 调度器中，小任务会被大任务阻塞。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">而对于Capacity调度器，有一个专门的队列用来运行小任务，但是为小任务专门设置一个队列会预先占用一定的集群资源，这就导致大任务的执行时间会落后于使用FIFO调度器时的时间。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">在Fair调度器中，我们不需要预先占用一定的系统资源，Fair调度器会为所有运行的job动态的调整系统资源。如下图所示，当第一个大job提交时，只有这一个job在运行，此时它获得了所有集群资源；当第二个小任务提交后，Fair调度器会分配一半资源给这个小任务，让这两个任务公平的共享集群资源。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">需要注意的是，在下图Fair调度器中，从第二个任务提交到获得资源会有一定的延迟，因为它需要等待第一个任务释放占用的Container。小任务执行完成之后也会释放自己占用的资源，大任务又获得了全部的系统资源。最终的效果就是Fair调度器即得到了高的资源利用率又能保证小任务及时完成。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;"><strong style="padding: 0px;"><em style="padding: 0px;">Yarn调度器对比图:</em></strong>&nbsp;<br data-filtered="filtered" style="padding: 0px;" /><img alt="技术分享" src="http://img.blog.csdn.net/20151030111100329" title="" style="padding: 0px; max-width: 680px; overflow: hidden;" /></p><h2>二、Capacity Scheduler（容器调度器）的配置</h2><h3>2.1 容器调度介绍</h3><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">Capacity 调度器允许多个组织共享整个集群，每个组织可以获得集群的一部分计算能力。通过为每个组织分配专门的队列，然后再为每个队列分配一定的集群资源，这样整个集群就可以通过设置多个队列的方式给多个组织提供服务了。除此之外，队列内部又可以垂直划分，这样一个组织内部的多个成员就可以共享这个队列资源了，在一个队列内部，资源的调度是采用的是先进先出(FIFO)策略。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">通过上面那幅图，我们已经知道一个job可能使用不了整个队列的资源。然而如果这个队列中运行多个job，如果这个队列的资源够用，那么就分配给这些job，如果这个队列的资源不够用了呢？其实Capacity调度器仍可能分配额外的资源给这个队列，这就是<strong style="padding: 0px;">&#8220;弹性队列&#8221;(queue elasticity)</strong>的概念。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">在正常的操作中，Capacity调度器不会强制释放Container，当一个队列资源不够用时，这个队列只能获得其它队列释放后的Container资源。当然，我们可以为队列设置一个最大资源使用量，以免这个队列过多的占用空闲资源，导致其它队列无法使用这些空闲资源，这就是&#8221;弹性队列&#8221;需要权衡的地方。</p><h3>2.2 容器调度的配置</h3><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">假设我们有如下层次的队列：</p><pre style="font-family: Arial, Helvetica, sans-serif; padding: 5px; background-color: #f6f6f6; border: 1px dotted #aaaaaa; white-space: pre-wrap; word-wrap: break-word; color: #3f3f3f;"><code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">root &#9500;&#9472;&#9472; prod &#9492;&#9472;&#9472; dev     &#9500;&#9472;&#9472; eng     &#9492;&#9472;&#9472; science </code></pre><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">下面是一个简单的Capacity调度器的配置文件，文件名为<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">capacity-scheduler.xml</code>。在这个配置中，在root队列下面定义了两个子队列<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev</code>，分别占40%和60%的容量。需要注意，一个队列的配置是通过属性<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">yarn.sheduler.capacity.&lt;queue-path&gt;.&lt;sub-property&gt;</code>指定的，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;queue-path&gt;</code>代表的是队列的继承树，如<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">root.prod</code>队列，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;sub-property&gt;</code>一般指<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">capacity</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">maximum-capacity</code>。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;"><img alt="技术分享" src="http://img.blog.csdn.net/20151030111921481" title="" style="padding: 0px; max-width: 680px; overflow: hidden;" /></p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">我们可以看到，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev</code>队列又被分成了<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">eng</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">science</code>两个相同容量的子队列。<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev</code>的<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">maximum-capacity</code>属性被设置成了75%，所以即使<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>队列完全空闲<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev</code>也不会占用全部集群资源，也就是说，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>队列仍有25%的可用资源用来应急。我们注意到，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">eng</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">science</code>两个队列没有设置<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">maximum-capacity</code>属性，也就是说<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">eng</code>或<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">science</code>队列中的job可能会用到整个<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev</code>队列的所有资源（最多为集群的75%）。而类似的，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>由于没有设置maximum-capacity属性，它有可能会占用集群全部资源。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">Capacity容器除了可以配置队列及其容量外，我们还可以配置一个用户或应用可以分配的最大资源数量、可以同时运行多少应用、队列的ACL认证等。</p><h3>2.3 队列的设置</h3><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">关于队列的设置，这取决于我们具体的应用。比如，在MapReduce中，我们可以通过<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">mapreduce.job.queuename</code>属性指定要用的队列。如果队列不存在，我们在提交任务时就会收到错误。如果我们没有定义任何队列，所有的应用将会放在一个<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">default</code>队列中。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">注意：对于Capacity调度器，我们的队列名必须是队列树中的最后一部分，如果我们使用队列树则不会被识别。比如，在上面配置中，我们使用<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">eng</code>作为队列名是可以的，但是如果我们用<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">root.dev.eng</code>或者<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev.eng</code>是无效的。</p><h2>三、Fair Scheduler（公平调度器）的配置</h2><h3>3.1 公平调度</h3><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">Fair调度器的设计目标是为所有的应用分配公平的资源（对公平的定义可以通过参数来设置）。在上面的<em style="padding: 0px;">&#8220;Yarn调度器对比图&#8221;</em>展示了一个队列中两个应用的公平调度；当然，公平调度在也可以在多个队列间工作。举个例子，假设有两个用户A和B，他们分别拥有一个队列。当A启动一个job而B没有任务时，A会获得全部集群资源；当B启动一个job后，A的job会继续运行，不过一会儿之后两个任务会各自获得一半的集群资源。如果此时B再启动第二个job并且其它job还在运行，则它将会和B的第一个job共享B这个队列的资源，也就是B的两个job会用于四分之一的集群资源，而A的job仍然用于集群一半的资源，结果就是资源最终在两个用户之间平等的共享。过程如下图所示：&nbsp;<br data-filtered="filtered" style="padding: 0px;" /><img alt="技术分享" src="http://img.blog.csdn.net/20151030112204338" title="" style="padding: 0px; max-width: 680px; overflow: hidden;" /></p><h3>3.2 启用Fair Scheduler</h3><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">调度器的使用是通过<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">yarn-site.xml</code>配置文件中的<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">yarn.resourcemanager.scheduler.class</code>参数进行配置的，默认采用Capacity Scheduler调度器。如果我们要使用Fair调度器，需要在这个参数上配置FairScheduler类的全限定名：&nbsp;<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</code>。</p><h3>3.3 队列的配置</h3><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">Fair调度器的配置文件位于类路径下的<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">fair-scheduler.xml</code>文件中，这个路径可以通过<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">yarn.scheduler.fair.allocation.file</code>属性进行修改。若没有这个配置文件，Fair调度器采用的分配策略，这个策略和3.1节介绍的类似：调度器会在用户提交第一个应用时为其自动创建一个队列，队列的名字就是用户名，所有的应用都会被分配到相应的用户队列中。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">我们可以在配置文件中配置每一个队列，并且可以像Capacity 调度器一样分层次配置队列。比如，参考<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">capacity-scheduler.xml</code>来配置fair-scheduler：&nbsp;<br data-filtered="filtered" style="padding: 0px;" /><img alt="技术分享" src="http://img.blog.csdn.net/20151030112334518" title="" style="padding: 0px; max-width: 680px; overflow: hidden;" /></p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">队列的层次是通过嵌套<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;queue&gt;</code>元素实现的。所有的队列都是<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">root</code>队列的孩子，即使我们没有配到<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;root&gt;</code>元素里。在这个配置中，我们把<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev</code>队列有分成了<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">eng</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">science</code>两个队列。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">Fair调度器中的队列有一个权重属性（这个权重就是对公平的定义），并把这个属性作为公平调度的依据。在这个例子中，当调度器分配集群<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">40:60</code>资源给<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev</code>时便视作公平，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">eng</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">science</code>队列没有定义权重，则会被平均分配。这里的权重并不是百分比，我们把上面的40和60分别替换成2和3，效果也是一样的。注意，对于在没有配置文件时按用户自动创建的队列，它们仍有权重并且权重值为1。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">每个队列内部仍可以有不同的调度策略。队列的默认调度策略可以通过顶级元素<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;defaultQueueSchedulingPolicy&gt;</code>进行配置，如果没有配置，默认采用公平调度。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">尽管是Fair调度器，其仍支持在队列级别进行FIFO调度。每个队列的调度策略可以被其内部的<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;schedulingPolicy&gt;</code>&nbsp;元素覆盖，在上面这个例子中，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>队列就被指定采用FIFO进行调度，所以，对于提交到<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>队列的任务就可以按照FIFO规则顺序的执行了。需要注意，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">prod</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev</code>之间的调度仍然是公平调度，同样<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">eng</code>和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">science</code>也是公平调度。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">尽管上面的配置中没有展示，每个队列仍可配置最大、最小资源占用数和最大可运行的应用的数量。</p><h3>3.4 队列的设置</h3><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">Fair调度器采用了一套基于规则的系统来确定应用应该放到哪个队列。在上面的例子中，<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;queuePlacementPolicy&gt;</code>&nbsp;元素定义了一个规则列表，其中的每个规则会被逐个尝试直到匹配成功。例如，上例第一个规则<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">specified</code>，则会把应用放到它指定的队列中，若这个应用没有指定队列名或队列名不存在，则说明不匹配这个规则，然后尝试下一个规则。<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">primaryGroup</code>规则会尝试把应用放在以<em style="padding: 0px;">用户所在的Unix组名</em>命名的队列中，如果没有这个队列，不创建队列转而尝试下一个规则。当前面所有规则不满足时，则触发<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">default</code>规则，把应用放在<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">dev.eng</code>队列中。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">当然，我们可以不配置<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">queuePlacementPolicy</code>规则，调度器则默认采用如下规则：</p><pre style="font-family: Arial, Helvetica, sans-serif; padding: 5px; background-color: #f6f6f6; border: 1px dotted #aaaaaa; white-space: pre-wrap; word-wrap: break-word; color: #3f3f3f;"><code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;queuePlacementPolicy&gt; &lt;rule name="specified" /&gt; &lt;rule name="user" /&gt; &lt;/queuePlacementPolicy&gt; </code></pre><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">上面规则可以归结成一句话，除非队列被准确的定义，否则会以用户名为队列名创建队列。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">还有一个简单的配置策略可以使得所有的应用放入同一个队列（default），这样就可以让所有应用之间平等共享集群而不是在用户之间。这个配置的定义如下：</p><pre style="font-family: Arial, Helvetica, sans-serif; padding: 5px; background-color: #f6f6f6; border: 1px dotted #aaaaaa; white-space: pre-wrap; word-wrap: break-word; color: #3f3f3f;"><code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;queuePlacementPolicy&gt; &lt;rule name="default" /&gt; &lt;/queuePlacementPolicy&gt; </code></pre><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">实现上面功能我们还可以不使用配置文件，直接设置<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">yarn.scheduler.fair.user-as-default-queue=false</code>，这样应用便会被放入default 队列，而不是各个用户名队列。另外，我们还可以设置<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">yarn.scheduler.fair.allow-undeclared-pools=false</code>，这样用户就无法创建队列了。</p><h3>3.5 抢占（Preemption）</h3><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">当一个job提交到一个繁忙集群中的空队列时，job并不会马上执行，而是阻塞直到正在运行的job释放系统资源。为了使提交job的执行时间更具预测性（可以设置等待的超时时间），Fair调度器支持抢占。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">抢占就是允许调度器杀掉占用超过其应占份额资源队列的containers，这些containers资源便可被分配到应该享有这些份额资源的队列中。需要注意抢占会降低集群的执行效率，因为被终止的containers需要被重新执行。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">可以通过设置一个全局的参数<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">yarn.scheduler.fair.preemption=true</code>来启用抢占功能。此外，还有两个参数用来控制抢占的过期时间（这两个参数默认没有配置，需要至少配置一个来允许抢占Container）：</p><pre style="font-family: Arial, Helvetica, sans-serif; padding: 5px; background-color: #f6f6f6; border: 1px dotted #aaaaaa; white-space: pre-wrap; word-wrap: break-word; color: #3f3f3f;"><code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">- minimum share preemption timeout - fair share preemption timeout </code></pre><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">如果队列在<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">minimum share preemption timeout</code>指定的时间内未获得最小的资源保障，调度器就会抢占containers。我们可以通过配置文件中的顶级元素<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;defaultMinSharePreemptionTimeout&gt;</code>为所有队列配置这个超时时间；我们还可以在<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;queue&gt;</code>元素内配置<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;minSharePreemptionTimeout&gt;</code>元素来为某个队列指定超时时间。</p><p style="font-family: Arial, Helvetica, sans-serif; padding: 0px; color: #3f3f3f; line-height: 30px; background-color: #ffffff;">与之类似，如果队列在<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">fair share preemption timeout</code>指定时间内未获得平等的资源的一半（这个比例可以配置），调度器则会进行抢占containers。这个超时时间可以通过顶级元素<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;defaultFairSharePreemptionTimeout&gt;</code>和元素级元素<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;fairSharePreemptionTimeout&gt;</code>分别配置所有队列和某个队列的超时时间。上面提到的比例可以通过<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;defaultFairSharePreemptionThreshold&gt;</code>(配置所有队列)和<code style="font-family: Arial, Helvetica, sans-serif; padding: 0px;">&lt;fairSharePreemptionThreshold&gt;</code>(配置某个队列)进行配置，默认是0.5。</p><div></div><img src ="http://www.blogjava.net/tjyhy590/aggbug/432722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-08-05 00:35 <a href="http://www.blogjava.net/tjyhy590/archive/2017/08/05/432722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hive大数据倾斜总结</title><link>http://www.blogjava.net/tjyhy590/archive/2017/07/31/432707.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Mon, 31 Jul 2017 11:57:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/07/31/432707.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432707.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/07/31/432707.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432707.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432707.html</trackback:ping><description><![CDATA[<p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">在做Shuffle阶段的优化过程中，遇到了数据倾斜的问题，造成了对一些情况下优化效果不明显。主要是因为在Job完成后的所得到的Counters是整个Job的总和，优化是基于这些Counters得出的平均值，而由于数据倾斜的原因造成map处理数据量的差异过大，使得这些平均值能代表的价值降低。Hive的执行是分阶段的，map处理数据量的差异取决于上一个stage的reduce输出，所以如何将数据均匀的分配到各个reduce中，就是解决数据倾斜的根本所在。规避错误来更好的运行比解决错误更高效。在查看了一些资料后，总结如下。</p><h1><strong>1数据倾斜的原因</strong></h1><h2><strong>1.1操作：</strong></h2><div align="center" style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"><table border="1" cellspacing="0" cellpadding="0" style="border-style: solid; border-color: silver; border-collapse: collapse; word-break: break-word;"><tbody><tr><td valign="top" width="104" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;"><strong>关键词</strong></p></td><td valign="top" width="180" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;"><strong>情形</strong></p></td><td valign="top" width="208" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;"><strong>后果</strong></p></td></tr><tr><td rowspan="2" width="104" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;"><strong>Join</strong></p></td><td valign="top" width="180" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">其中一个表较小，</p><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">但是key集中</p></td><td valign="top" width="208" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">分发到某一个或几个Reduce上的数据远高于平均值</p></td></tr><tr><td valign="top" width="180" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">大表与大表，但是分桶的判断字段0值或空值过多</p></td><td valign="top" width="208" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">这些空值都由一个reduce处理，灰常慢</p></td></tr><tr><td valign="top" width="104" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;"><strong>group by</strong></p></td><td valign="top" width="180" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">group by 维度过小，</p><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">某值的数量过多</p></td><td valign="top" width="208" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">处理某值的reduce灰常耗时</p></td></tr><tr><td valign="top" width="104" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;"><strong>Count Distinct</strong></p></td><td valign="top" width="180" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">某特殊值过多</p></td><td valign="top" width="208" style="font-size: 12px; border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><p align="center" style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">处理此特殊值的reduce耗时</p></td></tr></tbody></table></div><h2><strong>1.2原因：</strong></h2><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">1)、key分布不均匀</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">2)、业务数据本身的特性</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">3)、建表时考虑不周</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">4)、某些SQL语句本身就有数据倾斜</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><h2><strong>1.3表现：</strong></h2><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">任务进度长时间维持在99%（或100%），查看任务监控页面，发现只有少量（1个或几个）reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">单一reduce的记录数与平均记录数差异过大，通常可能达到3倍甚至更多。 最长时长远大于平均时长。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><h1><strong>2数据倾斜的解决方案</strong></h1><h2><strong>2.1参数调节：</strong></h2><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>hive.map.aggr=true</strong></p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Map 端部分聚合，相当于Combiner</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>hive.groupby.skewindata</strong><strong>=true</strong></p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">有数据倾斜的时候进行负载均衡，当选项设定为 true，生成的查询计划会有两个 MR Job。第一个 MR Job 中，Map 的输出结果集合会随机分布到 Reduce 中，每个 Reduce 做部分聚合操作，并输出结果，这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中，从而达到负载均衡的目的；第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中（这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中），最后完成最终的聚合操作。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><h2><strong>2.2 SQL语句调节：</strong></h2><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>如何</strong><strong>Join</strong><strong>：</strong></p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">关于驱动表的选取，选用join key分布最均匀的表作为驱动表</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">做好列裁剪和filter操作，以达到两表做join的时候，数据量相对变小的效果。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>大小表</strong><strong>Join</strong><strong>：</strong></p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">使用map join让小的维度表（1000条以下的记录条数） 先进内存。在map端完成reduce.</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>大表</strong><strong>Join</strong><strong>大表：</strong></p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">把空值的key变成一个字符串加上随机数，把倾斜的数据分到不同的reduce上，由于null值关联不上，处理后并不影响最终结果。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>count distinct</strong><strong>大量相同特殊值</strong></p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">count distinct时，将值为空的情况单独处理，如果是计算count distinct，可以不用处理，直接过滤，在最后结果中加1。如果还有其他计算，需要进行group by，可以先将值为空的记录单独处理，再和其他计算结果进行union。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>group by</strong><strong>维度过小：</strong></p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">采用sum() group by的方式来替换count(distinct)完成计算。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>特殊情况特殊处理：</strong></p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">在业务逻辑优化效果的不大情况下，有些时候是可以将倾斜的数据单独拿出来处理。最后union回去。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><h1><strong>3典型的业务场景</strong></h1><h2><strong>3.1空值产生的数据倾斜</strong></h2><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>场景：</strong>如日志中，常会有信息丢失的问题，比如日志中的 user_id，如果取其中的 user_id 和 用户表中的user_id 关联，会碰到数据倾斜的问题。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>解决方法</strong><strong>1</strong><strong>：</strong>&nbsp;user_id为空的不参与关联（红色字体为修改后）</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: navy; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #0000ff; line-height: 1.5 !important;">select</span> <span style="color: #808080; line-height: 1.5 !important;">*</span> <span style="color: #0000ff; line-height: 1.5 !important;">from</span> <span style="color: #ff00ff; line-height: 1.5 !important;">log</span><span style="line-height: 1.5 !important;"> a   </span><span style="color: #808080; line-height: 1.5 !important;">join</span><span style="line-height: 1.5 !important;"> users b   </span><span style="color: #0000ff; line-height: 1.5 !important;">on</span> a.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span> <span style="color: #0000ff; line-height: 1.5 !important;">is</span> <span style="color: #808080; line-height: 1.5 !important;">not</span> <span style="color: #0000ff; line-height: 1.5 !important;">null</span>   <span style="color: #808080; line-height: 1.5 !important;">and</span> a.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span> <span style="color: #808080; line-height: 1.5 !important;">=</span> b.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span> <span style="color: #0000ff; line-height: 1.5 !important;">union</span> <span style="color: #808080; line-height: 1.5 !important;">all</span> <span style="color: #0000ff; line-height: 1.5 !important;">select</span> <span style="color: #808080; line-height: 1.5 !important;">*</span> <span style="color: #0000ff; line-height: 1.5 !important;">from</span> <span style="color: #ff00ff; line-height: 1.5 !important;">log</span><span style="line-height: 1.5 !important;"> a   </span><span style="color: #0000ff; line-height: 1.5 !important;">where</span> a.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span> <span style="color: #0000ff; line-height: 1.5 !important;">is</span> <span style="color: #0000ff; line-height: 1.5 !important;">null</span>;</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: navy; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; border: none !important;" /></a></span></div></div><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>解决方法</strong><strong>2&nbsp;</strong><strong>：</strong>赋与空值分新的key值</p><div style="margin: 5px 0px; font-size: 12px !important;"><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #0000ff; line-height: 1.5 !important;">select</span> <span style="color: #808080; line-height: 1.5 !important;">*</span>   <span style="color: #0000ff; line-height: 1.5 !important;">from</span> <span style="color: #ff00ff; line-height: 1.5 !important;">log</span><span style="line-height: 1.5 !important;"> a   </span><span style="color: #808080; line-height: 1.5 !important;">left</span> <span style="color: #808080; line-height: 1.5 !important;">outer</span> <span style="color: #808080; line-height: 1.5 !important;">join</span><span style="line-height: 1.5 !important;"> users b   </span><span style="color: #0000ff; line-height: 1.5 !important;">on</span> <span style="color: #ff00ff; line-height: 1.5 !important;">case</span> <span style="color: #0000ff; line-height: 1.5 !important;">when</span> a.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span> <span style="color: #0000ff; line-height: 1.5 !important;">is</span> <span style="color: #0000ff; line-height: 1.5 !important;">null</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span> concat(&#8216;hive&#8217;,<span style="color: #ff00ff; line-height: 1.5 !important;">rand</span>() ) <span style="color: #0000ff; line-height: 1.5 !important;">else</span> a.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span> <span style="color: #808080; line-height: 1.5 !important;">=</span> b.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span>;</pre></div><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>结论：</strong>方法2比方法1效率更好，不但io少了，而且作业数也少了。解决方法1中 log读取两次，jobs是2。解决方法2 job数是1 。这个优化适合无效 id (比如 -99 , &#8217;&#8217;, null 等) 产生的倾斜问题。把空值的 key 变成一个字符串加上随机数，就能把倾斜的数据分到不同的reduce上 ,解决数据倾斜问题。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><h2><strong>3.2不同数据类型关联产生数据倾斜</strong></h2><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>场景：</strong>用户表中user_id字段为int，log表中user_id字段既有string类型也有int类型。当按照user_id进行两个表的Join操作时，默认的Hash操作会按int型的id来进行分配，这样会导致所有string类型id的记录都分配到一个Reducer中。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>解决方法：</strong>把数字类型转换成字符串类型</p><div style="margin: 5px 0px; font-size: 12px !important;"><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #0000ff; line-height: 1.5 !important;">select</span> <span style="color: #808080; line-height: 1.5 !important;">*</span> <span style="color: #0000ff; line-height: 1.5 !important;">from</span><span style="line-height: 1.5 !important;"> users a   </span><span style="color: #808080; line-height: 1.5 !important;">left</span> <span style="color: #808080; line-height: 1.5 !important;">outer</span> <span style="color: #808080; line-height: 1.5 !important;">join</span><span style="line-height: 1.5 !important;"> logs b   </span><span style="color: #0000ff; line-height: 1.5 !important;">on</span> a.usr_id <span style="color: #808080; line-height: 1.5 !important;">=</span> <span style="color: #ff00ff; line-height: 1.5 !important;">cast</span>(b.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span> <span style="color: #0000ff; line-height: 1.5 !important;">as</span> string)</pre></div><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><h2><strong>3.3小表不小不大，怎么用 map join 解决倾斜问题</strong></h2><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">使用 map join 解决小表(记录数少)关联大表的数据倾斜问题，这个方法使用的频率非常高，但如果小表很大，大到map join会出现bug或异常，这时就需要特别的处理。&nbsp;<strong>以下例子</strong><strong>:</strong></p><div style="margin: 5px 0px; font-size: 12px !important;"><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #0000ff; line-height: 1.5 !important;">select</span> <span style="color: #808080; line-height: 1.5 !important;">*</span> <span style="color: #0000ff; line-height: 1.5 !important;">from</span> <span style="color: #ff00ff; line-height: 1.5 !important;">log</span><span style="line-height: 1.5 !important;"> a   </span><span style="color: #808080; line-height: 1.5 !important;">left</span> <span style="color: #808080; line-height: 1.5 !important;">outer</span> <span style="color: #808080; line-height: 1.5 !important;">join</span><span style="line-height: 1.5 !important;"> users b   </span><span style="color: #0000ff; line-height: 1.5 !important;">on</span> a.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span> <span style="color: #808080; line-height: 1.5 !important;">=</span> b.<span style="color: #ff00ff; line-height: 1.5 !important;">user_id</span>;</pre></div><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">users 表有 600w+ 的记录，把 users 分发到所有的 map 上也是个不小的开销，而且 map join 不支持这么大的小表。如果用普通的 join，又会碰到数据倾斜的问题。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong>解决方法：</strong></p><div style="margin: 5px 0px; font-size: 12px !important;"><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;">select /*+mapjoin(x)*/* from log a   <br />left outer join (     <br />select  /*+mapjoin(c)*/d.*  from ( <br />select distinct user_id from log ) c  join users d       <br />on c.user_id = d.user_id     ) x   <br />on a.user_id = b.user_id;  </pre><div style="margin-top: 5px;"></div></div><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">假如，log里user_id有上百万个，这就又回到原来map join问题。所幸，每日的会员uv不会太多，有交易的会员不会太多，有点击的会员不会太多，有佣金的会员不会太多等等。所以这个方法能解决很多场景下的数据倾斜问题。</p><h1><strong>4总结</strong></h1><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">使map的输出数据更均匀的分布到reduce中去，是我们的最终目标。由于Hash算法的局限性，按key Hash会或多或少的造成数据倾斜。大量经验表明数据倾斜的原因是人为的建表疏忽或业务逻辑可以规避的。在此给出较为通用的步骤：</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">1、采样log表，哪些user_id比较倾斜，得到一个结果表tmp1。由于对计算框架来说，所有的数据过来，他都是不知道数据分布情况的，所以采样是并不可少的。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">2、数据的分布符合社会学统计规则，贫富不均。倾斜的key不会太多，就像一个社会的富人不多，奇特的人不多一样。所以tmp1记录数会很少。把tmp1和users做map join生成tmp2,把tmp2读到distribute file cache。这是一个map过程。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">3、map读入users和log，假如记录来自log,则检查user_id是否在tmp2里，如果是，输出到本地文件a,否则生成&lt;user_id,value&gt;的key,value对，假如记录来自member,生成&lt;user_id,value&gt;的key,value对，进入reduce阶段。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">4、最终把a文件，把Stage3 reduce阶段输出的文件合并起写到hdfs。</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">如果确认业务需要这样倾斜的逻辑，考虑以下的优化方案：</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">1、对于join，在判断小表不大于1G的情况下，使用map join</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">2、对于group by或distinct，设定&nbsp;hive.groupby.skewindata=true</p><p style="font-size: 13px; line-height: 1.5; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">3、尽量使用上述的SQL语句调节进行优化</p><img src ="http://www.blogjava.net/tjyhy590/aggbug/432707.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-07-31 19:57 <a href="http://www.blogjava.net/tjyhy590/archive/2017/07/31/432707.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HIVE和HBASE区别</title><link>http://www.blogjava.net/tjyhy590/archive/2017/07/21/432677.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Fri, 21 Jul 2017 03:44:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/07/21/432677.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432677.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/07/21/432677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432677.html</trackback:ping><description><![CDATA[<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">1. 两者分别是什么？</font>&nbsp;&nbsp;</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp;<font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">Apache Hive</font>是一个构建在Hadoop基础设施之上的数据仓库。通过Hive可以使用HQL语言查询存放在HDFS上的数据。HQL是一种类SQL语言，这种语言最终被转化为Map/Reduce. 虽然Hive提供了SQL查询功能，但是Hive不能够进行交互查询--因为它只能够在Haoop上批量的执行Hadoop。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span><font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">Apache HBase</font>是一种Key/Value系统，它运行在HDFS之上。和Hive不一样，Hbase的能够在它的数据库上实时运行，而不是运行MapReduce任务。Hive被分区为表格，表格又被进一步分割为列簇。列簇必须使用schema定义，列簇将某一类型列集合起来（列不要求schema定义）。例如，&#8220;message&#8221;列簇可能包含：&#8220;to&#8221;, &#8221;from&#8221; &#8220;date&#8221;, &#8220;subject&#8221;, 和&#8221;body&#8221;. 每一个 key/value对在Hbase中被定义为一个cell，每一个key由row-key，列簇、列和时间戳。在Hbase中，行是key/value映射的集合，这个映射通过row-key来唯一标识。Hbase利用Hadoop的基础设施，可以利用通用的设备进行水平的扩展。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">2.<span class="Apple-converted-space">&nbsp;</span><font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">两者的特点</font></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp;<span class="Apple-converted-space">&nbsp;</span><font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">Hive</font>帮助熟悉SQL的人运行MapReduce任务。因为它是JDBC兼容的，同时，它也能够和现存的SQL工具整合在一起。运行Hive查询会花费很长时间，因为它会默认遍历表中所有的数据。虽然有这样的缺点，一次遍历的数据量可以通过Hive的分区机制来控制。分区允许在数据集上运行过滤查询，这些数据集存储在不同的文件夹内，查询的时候只遍历指定文件夹（分区）中的数据。这种机制可以用来，例如，只处理在某一个时间范围内的文件，只要这些文件名中包括了时间格式。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp;&nbsp;&nbsp; HBase通过存储key/value来工作。它支持四种主要的操作：增加或者更新行，查看一个范围内的cell，获取指定的行，删除指定的行、列或者是列的版本。版本信息用来获取历史数据（每一行的历史数据可以被删除，然后通过Hbase compactions就可以释放出空间）。虽然HBase包括表格，但是schema仅仅被表格和列簇所要求，列不需要schema。Hbase的表格包括增加/计数功能。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">3.<font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff"><span class="Apple-converted-space">&nbsp;</span>限制</font></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp; Hive目前不支持更新操作。另外，由于hive在hadoop上运行批量操作，它需要花费很长的时间，通常是几分钟到几个小时才可以获取到查询的结果。Hive必须提供预先定义好的schema将文件和目录映射到列，并且Hive与ACID不兼容。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp;&nbsp;&nbsp; HBase查询是通过特定的语言来编写的，这种语言需要重新学习。类SQL的功能可以通过Apache Phonenix实现，但这是以必须提供schema为代价的。另外，Hbase也并不是兼容所有的ACID特性，虽然它支持某些特性。最后但不是最重要的--为了运行Hbase，<font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">Zookeeper是必须的</font>，zookeeper是一个用来进行分布式协调的服务，这些服务包括配置服务，维护元信息和命名空间服务。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">4.<span class="Apple-converted-space">&nbsp;</span><font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">应用场景</font></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp;&nbsp;&nbsp; Hive适合用来对一段时间内的数据进行分析查询，例如，用来计算趋势或者网站的日志。Hive不应该用来进行实时的查询。因为它需要很长时间才可以返回结果。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp;&nbsp;&nbsp; Hbase非常适合用来进行大数据的实时查询。Facebook用Hbase进行消息和实时的分析。它也可以用来统计Facebook的连接数。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">5.<span class="Apple-converted-space">&nbsp;</span><font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">总结</font></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; font: medium/28px Verdana, Arial, Helvetica, sans-serif; padding-left: 0px; widows: 1; margin: 10px auto; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">&nbsp;&nbsp;&nbsp; Hive和Hbase是两种基于Hadoop的不同技术--Hive是一种类SQL的引擎，并且运行MapReduce任务，Hbase是一种在Hadoop之上的NoSQL 的Key/vale数据库。当然，这两种工具是可以<font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">同时使用</font>的。就像用Google来搜索，用FaceBook进行社交一样，Hive可以用来进行<font style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px" color="#0000ff">统计查询</font>，HBase可以用来进行实时查询，数据也可以从Hive写到Hbase，设置再从Hbase写回Hive。</p><img src ="http://www.blogjava.net/tjyhy590/aggbug/432677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-07-21 11:44 <a href="http://www.blogjava.net/tjyhy590/archive/2017/07/21/432677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hive分布式安装配置Hive+Mysql</title><link>http://www.blogjava.net/tjyhy590/archive/2017/07/20/432675.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Thu, 20 Jul 2017 07:20:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/07/20/432675.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432675.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/07/20/432675.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432675.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432675.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 目录&nbsp;1，环境准备&nbsp;2，安装Hive和配置环境变量&nbsp;3，安装MySQL&nbsp;4，在mysql上创建hive元数据库，并对hive进行授权&nbsp;5，安装jar包到hive&nbsp;6，配置hive-site.xml&nbsp;7，元数据存储初始化&nbsp;8，启动验证hive&nbsp;9，报错及解决方法1，环境准备：准备好Hadoop集群，参照...&nbsp;&nbsp;<a href='http://www.blogjava.net/tjyhy590/archive/2017/07/20/432675.html'>阅读全文</a><img src ="http://www.blogjava.net/tjyhy590/aggbug/432675.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-07-20 15:20 <a href="http://www.blogjava.net/tjyhy590/archive/2017/07/20/432675.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> TCP/UDP区别以及UDP如何实现可靠传输</title><link>http://www.blogjava.net/tjyhy590/archive/2017/07/19/432672.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Wed, 19 Jul 2017 14:25:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/07/19/432672.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432672.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/07/19/432672.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432672.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432672.html</trackback:ping><description><![CDATA[<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">TCP和UDP是OSI模型中的运输层中的协议。TCP提供可靠的通信传输，而UDP则常被用于让广播和细节控制交给应用的通信传输。</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><br /></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">UDP(User Datagram Protocol)</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">&nbsp; &nbsp; &nbsp; &nbsp; UDP不提供复杂的控制机制，利用IP提供面向无连接的通信服务。并且它是将应用程序发来的数据在收到的那一刻，立刻按照原样发送到网络上的一种机制。</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">&nbsp; &nbsp; &nbsp; &nbsp; 即使是出现网络拥堵的情况下，UDP也无法进行流量控制等避免网络拥塞的行为。此外，传输途中如果出现了丢包，UDO也不负责重发。甚至当出现包的到达顺序乱掉时也没有纠正的功能。如果需要这些细节控制，那么不得不交给由采用UDO的应用程序去处理。换句话说，UDP将部分控制转移到应用程序去处理，自己却只提供作为传输层协议的最基本功能。UDP有点类似于用户说什么听什么的机制，但是需要用户充分考虑好上层协议类型并制作相应的应用程序。</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><br /></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">TCP(Transmission Control Protocol)</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">&nbsp; &nbsp; &nbsp; &nbsp; TCP充分实现爱呢了数据传输时各种控制功能，可以进行丢包的重发控制，还可以对次序乱掉的分包进行顺序控制。而这些在UDP中都没有。此外，TCP作为一种面向有连接的协议，只有在确认通信对端存在时才会发送数据，从而可以控制通信流量的浪费。</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">&nbsp; &nbsp; &nbsp; &nbsp; TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。此处不一一叙述。</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><br /></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">TCP与UDP如何加以区分使用？</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">&nbsp; &nbsp; &nbsp; &nbsp; TCP用于在传输层有必要实现可靠性传输的情况。由于它是面向有连接并具备顺序控制、重发控制等机制的。所以它可以为应用提供可靠传输。</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">&nbsp; &nbsp; &nbsp; &nbsp; 另一方面，UDP主要用于那些对高速传输和实时性有较高要求的通信或广播通信。举一个IP电话进行通话的例子。如果使用TCP，数据在传送途中如果丢失会被重发，但是这样无法流畅地传输通话人的声音，会导致无法进行正常交流。而采用UDP，它不会进行重发处理。从而也就不会有声音大幅度延迟到达的问题。即使有部分数据丢失，也只是影响某一小部分的通话。此外，在多播与广播通信中也使用UDP而不是UDP。RIP、DHCP等基于广播的协议也要依赖于UDP。</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><br /></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><strong>TCP与UDP区别总结：</strong></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">1、TCP面向连接（如打电话要先拨号建立连接）;UDP是无连接的，即发送数据之前不需要建立连接</span></span></p><span style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px 'Microsoft YaHei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-size: 14px">2、TCP提供可靠的服务。也就是说，通过TCP连接传送的数据，无差错，不丢失，不重复，且按序到达;UDP尽最大努力交付，即不保证可靠交付<br />3、TCP面向字节流，实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的<br />UDP没有拥塞控制，因此网络出现拥塞不会使源主机的发送速率降低（对实时应用很有用，如IP电话，实时视频会议等）<br />4、每一条TCP连接只能是点到点的;UDP支持一对一，一对多，多对一和多对多的交互通信<br />5、TCP首部开销20字节;UDP的首部开销小，只有8个字节<br /></span></span><span style="white-space: normal; word-spacing: 0px; text-transform: none; float: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"></span>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px">6、TCP的逻辑通信信道是全双工的可靠信道，UDP则是不可靠信道</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><strong><br /></strong></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><strong>UDP如何实现可靠传输</strong></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><span style="font-size: 14px; font-family: Arial; line-height: 26px">由于在传输层UDP已经是不可靠的连接，那就要在应用层自己实现一些保障可靠传输的机制</span></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><span style="font-size: 14px; font-family: Arial; line-height: 26px">简单来讲，要使用UDP来构建可靠的面向连接的数据传输，就要实现类似于TCP协议的</span></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><span style="font-size: 14px; font-family: Arial; line-height: 26px"><span style="white-space: pre"></span>超时重传（定时器）</span></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><span style="font-size: 14px; font-family: Arial; line-height: 26px"><span style="white-space: pre"></span>有序接受 （添加包序号）</span></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><span style="font-size: 14px; font-family: Arial; line-height: 26px"><span style="white-space: pre"></span>应答确认 （Seq/Ack应答机制）</span></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><span style="font-size: 14px; font-family: Arial; line-height: 26px"><span style="white-space: pre"></span>滑动窗口流量控制等机制 （滑动窗口协议）</span></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: 'Microsoft YaHei'"><span style="font-size: 14px"><span style="font-size: 14px; font-family: Arial; line-height: 26px">等于说要在传输层的上一层（或者直接在应用层）实现TCP协议的可靠数据传输机制，比如使用UDP数据包+序列号，UDP数据包+时间戳等方法。</span><br /></span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: Arial"><span style="font-size: 14px; line-height: 26px">目前已经有一些实现UDP可靠传输的机制，比如</span></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-family: Arial"><span style="font-size: 14px; line-height: 26px"></span></span></p>
<h3 style="font-family: Arial; font-variant: normal; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); padding-bottom: 0px; font-style: normal; text-align: left; padding-top: 0px; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; line-height: 26px; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-weight: normal">UDT（<span style="font-size: 14px; font-family: arial, 宋体, sans-serif; line-height: 25px">UDP-based Data Transfer Protocol</span>）</span></h3>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(54,46,43); text-align: left; font: 14px/26px Arial; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="font-size: 14px; font-family: arial, 宋体, sans-serif; line-height: 25px">基于UDP的数据传输协议（UDP-based Data Transfer Protocol，简称UDT）是一种互联网数据传输协议。UDT的主要目的是</span><span style="font-size: 14px; font-family: arial, 宋体, sans-serif; line-height: 25px">支持高速广域网上的海量数据传输</span><span style="font-size: 14px; font-family: arial, 宋体, sans-serif; line-height: 25px">，而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。 顾名思义，</span><span style="font-size: 14px; font-family: arial, 宋体, sans-serif; line-height: 25px">UDT建于UDP之上，并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。</span><span style="font-size: 14px; font-family: arial, 宋体, sans-serif; line-height: 25px">&nbsp;由于UDT完全在UDP上实现，它也可以应用在除了高速数据传输之外的其它应用领域，例如点到点技术（P2P），防火墙穿透，多媒体数据传输等等。</span></div><img src ="http://www.blogjava.net/tjyhy590/aggbug/432672.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-07-19 22:25 <a href="http://www.blogjava.net/tjyhy590/archive/2017/07/19/432672.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一文读懂分布式数据库Hbase</title><link>http://www.blogjava.net/tjyhy590/archive/2017/07/19/432671.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Wed, 19 Jul 2017 14:24:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/07/19/432671.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432671.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/07/19/432671.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432671.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432671.html</trackback:ping><description><![CDATA[<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">一、</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">1、什么是<a title="Hbase知识库" class="replace_word" style="text-decoration: none; font-weight: bold; color: rgb(223,52,52)" href="http://lib.csdn.net/base/hbase" target="_blank">Hbase</a>。</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">是</span><span style="color: black">一个高可靠性、高性能、列存储、可伸缩、实时读写的分布式<a title="MySQL知识库" class="replace_word" style="text-decoration: none; font-weight: bold; color: rgb(223,52,52)" href="http://lib.csdn.net/base/mysql" target="_blank">数据库</a>系统。</span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">适合于存储非结构化</span><span style="color: black">数据，基于列的而不是基于行的模式</span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">如图：<a title="Hadoop知识库" class="replace_word" style="text-decoration: none; font-weight: bold; color: rgb(223,52,52)" href="http://lib.csdn.net/base/hadoop" target="_blank">Hadoop</a>生态中<a title="Hbase知识库" class="replace_word" style="text-decoration: none; font-weight: bold; color: rgb(223,52,52)" href="http://lib.csdn.net/base/hbase" target="_blank">hbase</a>与其他部分的关系。<br /></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black"><img style="max-width: 100%; border-top: medium none; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161130231654148" /><br /></span></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">2、关系数据库已经流行很多年，并且<a title="Hadoop知识库" class="replace_word" style="text-decoration: none; font-weight: bold; color: rgb(223,52,52)" href="http://lib.csdn.net/base/hadoop" target="_blank">hadoop</a>已经有了HDFS和MapReduce，为什么需要HBase?</p>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">Hadoop</span><span style="color: black">可以很好地解决大规模数据的离线批量处理问题，但是，受限于</span><span style="color: black">HadoopMapReduce</span><span style="color: black">编程框架的高延迟数据处理机制，使得</span><span style="color: black">Hadoop</span><span style="color: black">无法满足大规模数据实时处理应用的需求</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">HDFS</span><span style="color: black">面向批量访问模式，不是随机访问模式</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">传统的通用关系型数据库无法应对在数据规模剧增时导致的系统扩展性和性能问题（分库分表也不能很好解决）</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">传统关系数据库在数据结构变化时一般需要停机维护；空列浪费存储空间</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">因此，业界出现了一类面向半结构化数据存储和处理的高可扩展、低写入</span><span style="color: black">/</span><span style="color: black">查询延迟的系统，例如，键值数据库、文档数据库和列族数据库（如</span><span style="color: black">BigTable</span><span style="color: black">和</span><span style="color: black">HBase</span><span style="color: black">等）</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">HBase</span><span style="color: black">已经成功应用于互联网服务领域和传统行业的众多在线式数据分析处理系统中</span></div><span style="white-space: normal; word-spacing: 0px; text-transform: none; float: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">3、</span><span style="white-space: normal; word-spacing: 0px; text-transform: none; color: black; font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">HBase</span><span style="white-space: normal; word-spacing: 0px; text-transform: none; color: black; font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">与传统的关系数据库的区别</span><span style="white-space: normal; word-spacing: 0px; text-transform: none; float: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"></span> 
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"></p>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">（</span><span style="color: black">1</span><span style="color: black">）数据类型：关系数据库采用关系模型，具有丰富的数据类型和存储方式，</span><span style="color: rgb(255,0,0)">HBase则采用了更加简单的数据模型，它把数据存储为未经解释的字符串</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">（</span><span style="color: black">2</span><span style="color: black">）数据操作：关系数据库中包含了丰富的操作，其中会涉及复杂的多表连接。</span><span style="color: rgb(255,0,0)">HBase</span><span style="color: black"><span style="color: rgb(255,0,0)">操作则不存在复杂的表与表之间的关系，只有简单的插入、查询、删除、清空等</span>，因为</span><span style="color: black">HBase</span><span style="color: black">在设计上就避免了复杂的表和表之间的关系<br />（</span><span style="color: black">3</span><span style="color: black">）存储模式：关系数据库是基于行模式存储的。</span><span style="color: rgb(255,0,0)">HBase是基于列存储的，每个列族都由几个文件保存，不同列族的文件是分离的</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">（</span><span style="color: black">4</span><span style="color: black">）数据索引：关系数据库通常可以针对不同列构建复杂的多个索引，以提高数据访问性能。</span><span style="color: rgb(255,0,0)">HBase只有一个索引&#8212;&#8212;行键，通过巧妙的设计，HBase中的所有访问方法，或者通过行键访问，或者通过行键扫描，从而使得整个系统不会慢下来</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">（</span><span style="color: black">5</span><span style="color: black">）数据维护：在关系数据库中，更新操作会用最新的当前值去替换记录中原来的旧值，旧值被覆盖后就不会存在。而<span style="color: rgb(255,0,0)">在</span></span><span style="color: rgb(255,0,0)">HBase中执行更新操作时，并不会删除数据旧的版本，而是生成一个新的版本，旧有的版本仍然保留</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">（</span><span style="color: black">6</span><span style="color: black">）可伸缩性：关系数据库很难实现横向扩展，纵向扩展的空间也比较有限。相反，</span><span style="color: rgb(255,0,0)">HBase和BigTable这些分布式数据库就是为了实现灵活的水平扩展而开发的，能够轻易地通过在集群中增加或者减少硬件数量来实现性能的伸缩</span></div><span style="white-space: normal; word-spacing: 0px; text-transform: none; float: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">二、Hbase数据模型</span> 
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">1、模型概述</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"></p>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">HBase</span><span style="color: black">是一个稀疏、多维度、排序的映射表，这张表的索引是行键、列族、列限定符和时间戳</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">每个值是一个未经解释的字符串，没有数据类型</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">用户在表中存储数据，每一行都有一个可排序的行键和任意多的列</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">表在水平方向由一个或者多个列族组成，一个列族中可以包含任意多个列，同一个列族里面的数据存储在一起</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">列族支持动态扩展，可以很轻松地添加一个列族或列，无需预先定义列的数量以及类型，所有列均以字符串形式存储，用户需要自行进行数据类型转换</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">HBase</span><span style="color: black">中执行更新操作时，并不会删除数据旧的版本，而是生成一个新的版本，旧有的版本仍然保留（这是和</span><span style="color: black">HDFS</span><span style="color: black">只允许追加不允许修改的特性相关的）<br /><img style="max-width: 100%; border-top: medium none; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161130232851396" width="891" height="372" /><br /></span>
<div><span style="color: black">2、数据坐标<br />HBase</span><span style="color: black">中需要根据行键、列族、列限定符和时间戳来确定一个单元格，因此，可以视为一个&#8220;四维坐标&#8221;，即</span><span style="color: black">[</span><span style="color: black">行键</span><span style="color: black">,</span><span style="color: black">列族</span><span style="color: black">,<span class="Apple-converted-space">&nbsp;</span></span><span style="color: black">列限定符</span><span style="color: black">,</span><span style="color: black">时间戳</span><span style="color: black">]</span></div>
<table cellspacing="0" cellpadding="0" width="848" border="0">
<colgroup>
<col width="548">
<col width="300"></colgroup>
<tbody>
<tr height="45">
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">键</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">值</span></p></td></tr>
<tr height="39">
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">[</span><span style="color: black">&#8220;</span><span style="color: black">201505003</span><span style="color: black">&#8221;</span><span style="color: black">,</span><span style="color: black">&#8220;</span><span style="color: black">Info</span><span style="color: black">&#8221;</span><span style="color: black">,</span><span style="color: black">&#8220;</span><span style="color: black">email</span><span style="color: black">&#8221;</span><span style="color: black">, 1174184619081]</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">&#8220;</span><span style="color: black">xie@qq.com</span><span style="color: black">&#8221;</span></p></td></tr>
<tr height="69">
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">[</span><span style="color: black">&#8220;</span><span style="color: black">201505003</span><span style="color: black">&#8221;</span><span style="color: black">,</span><span style="color: black">&#8220;</span><span style="color: black">Info</span><span style="color: black">&#8221;</span><span style="color: black">,</span><span style="color: black">&#8220;</span><span style="color: black">email</span><span style="color: black">&#8221;</span><span style="color: black">, 1174184620720]</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">&#8220;</span><span style="color: black">you@163.com</span><span style="color: black">&#8221;</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black"><br /></span></p></td></tr></tbody></table>3、概念视图<br /></div>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><img style="max-width: 602px; border-top: medium none; height: auto; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161130233320372" width="862" height="369" /></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">4、物理视图<br /></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><img style="max-width: 602px; border-top: medium none; height: auto; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161130233215264" width="764" height="330" /><br /></p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">三、HBase实现原理</p>
<p style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); padding-bottom: 0px; padding-top: 0px; font: 15px/35px 'microsoft yahei'; padding-left: 0px; widows: 1; margin: 0px; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">1、<span style="color: black">HBase</span><span style="color: black">的实现包括三个主要的功能组件：</span></p>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">（</span><span style="color: black">1</span><span style="color: black">）库函数：链接到每个客户端</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">（</span><span style="color: black">2</span><span style="color: black">）一个</span><span style="color: black">Master</span><span style="color: black">主服务器</span></div>
<div style="white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(85,85,85); font: 15px/35px 'microsoft yahei'; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px"><span style="color: black">（</span><span style="color: black">3</span><span style="color: black">）许多个</span><span style="color: black">Region</span><span style="color: black">服务器<br /></span>
<div><span style="color: black">主服务器Master负责管理和维护HBase表的分区信息</span><span style="color: black">，维护</span><span style="color: black">Region</span><span style="color: black">服务器列表，分配</span><span style="color: black">Region</span><span style="color: black">，负载均衡</span></div>
<div><span style="color: black">Region</span><span style="color: black">服务器负责存储和维护分配给自己的</span><span style="color: black">Region</span><span style="color: black">，处理来自客户端的读写请求</span></div>
<div><span style="color: black">客户端并不是直接从</span><span style="color: black">Master</span><span style="color: black">主服务器上读取数据，而是在获得</span><span style="color: black">Region</span><span style="color: black">的存储位置信息后，直接从</span><span style="color: black">Region</span><span style="color: black">服务器上读取数据</span></div>
<div><span style="color: black">客户端并不依赖</span><span style="color: black">Master</span><span style="color: black">，而是通过</span><span style="color: black">Zookeeper</span><span style="color: black">来获得</span><span style="color: black">Region</span><span style="color: black">位置信息，大多数客户端甚至从来不和</span><span style="color: black">Master</span><span style="color: black">通信，这种设计方式使得</span><span style="color: black">Master</span><span style="color: black">负载很小<br /></span>
<div><span style="color: black"><span style="color: black"><span style="color: black"><span style="color: black">2、Region</span></span></span><br />开始只有一个</span><span style="color: black">Region</span><span style="color: black">，后来不断分裂</span></div>
<div><span style="color: black">Region</span><span style="color: black">拆分操作非常快，接近瞬间，因为拆分之后的</span><span style="color: black">Region</span><span style="color: black">读取的仍然是原存储文件，直到&#8220;合并&#8221;过程把存储文件异步地写到独立的文件之后，才会读取新文件</span></div>
<div><span style="color: black">同一个</span><span style="color: black">Region</span><span style="color: black">不会被分拆到多个</span><span style="color: black">Region</span><span style="color: black">服务器<br /></span>
<div><span style="color: black">每个</span><span style="color: black">Region</span><span style="color: black">服务器存储</span><span style="color: black">10-1000</span><span style="color: black">个</span><span style="color: black">Region<br /><br /></span>
<div><span style="color: black">元数据表，又名</span><span style="color: black">.META.</span><span style="color: black">表，存储了</span><span style="color: black">Region</span><span style="color: black">和</span><span style="color: black">Region</span><span style="color: black">服务器的映射关系</span></div>
<div><span style="color: black">当</span><span style="color: black">HBase</span><span style="color: black">表很大时，</span><span style="color: black"><span class="Apple-converted-space">&nbsp;</span>.META.</span><span style="color: black">表也会被分裂成多个</span><span style="color: black">Region</span></div>
<div><span style="color: black">根数据表，又名</span><span style="color: black">-ROOT-</span><span style="color: black">表，记录所有元数据的具体位置</span></div>
<div><span style="color: black">-ROOT-</span><span style="color: black">表只有唯一一个</span><span style="color: black">Region</span><span style="color: black">，名字是在程序中被写死的</span></div>
<div><span style="color: black">Zookeeper</span><span style="color: black">文件记录了</span><span style="color: black">-ROOT-</span><span style="color: black">表的位置</span></div><br /></div></div><img style="max-width: 100%; border-top: medium none; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161130234043048" width="736" height="236" /><br />
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">客户端访问数据时的&#8220;三级寻址&#8221;</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">为了加速寻址，客户端会缓存位置信息，同时，需要解决缓存失效问题</span></p>
<div><span style="color: black">寻址过程客户端只需要询问</span><span style="color: black">Zookeeper</span><span style="color: black">服务器，不需要连接</span><span style="color: black">Master</span><span style="color: black">服务器</span></div>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">3、HBase</span><span style="color: black">的三层结构中各层次的名称和作用</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black"></span></p>
<table height="245" cellspacing="0" cellpadding="0" width="813" border="0">
<colgroup>
<col width="111">
<col width="181">
<col width="533"></colgroup>
<tbody>
<tr height="42">
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">层次</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">名称</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">作用</span></p></td></tr>
<tr height="74">
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">第一层</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">Zookeper</span><span style="color: black">文件</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">记录了</span><span style="color: black">-ROOT-</span><span style="color: black">表的位置信息</span></p></td></tr>
<tr height="106">
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">第二层</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">-ROOT-</span><span style="color: black">表</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">记录了</span><span style="color: black">.META.</span><span style="color: black">表的</span><span style="color: black">Region</span><span style="color: black">位置信息</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">-ROOT-</span><span style="color: black">表只能有一个</span><span style="color: black">Region</span><span style="color: black">。通过</span><span style="color: black">-ROOT-</span><span style="color: black">表，就可以访问</span><span style="color: black">.META.</span><span style="color: black">表中的数据</span></p></td></tr>
<tr height="106">
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">第三层</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">.META.</span><span style="color: black">表</span></p></td>
<td>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">记录了用户数据表的</span><span style="color: black">Region</span><span style="color: black">位置信息，</span><span style="color: black">.META.</span><span style="color: black">表可以有多个</span><span style="color: black">Region</span><span style="color: black">，保存了</span><span style="color: black">HBase</span><span style="color: black">中所有用户数据表的</span><span style="color: black">Region</span><span style="color: black">位置信息</span></p></td></tr></tbody></table>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"></p><span style="color: black">四、HBase运行机制<br />1、HBase系统架构<br /><img style="max-width: 100%; border-top: medium none; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161130234450831" width="907" height="443" /><br /><br /></span>
<div><span style="color: black">(1、客户端包含访问</span><span style="color: black">HBase</span><span style="color: black">的接口，同时在缓存中维护着已经访问过的</span><span style="color: black">Region</span><span style="color: black">位置信息，用来加快后续数据访问过程</span></div><br /><span style="color: black"></span>
<div><span style="color: black">(2、Zookeeper</span><span style="color: black">可以帮助选举出一个</span><span style="color: black">Master</span><span style="color: black">作为集群的总管，并保证在任何时刻总有唯一一个</span><span style="color: black">Master</span><span style="color: black">在运行，这就避免了</span><span style="color: black">Master</span><span style="color: black">的&#8220;单点失效&#8221;问题</span></div><span style="color: black">（<span style="color: black"><span style="color: black">Zookeeper是一个很好的集群管理工具，被大量用于分布式计算，提供配置维护、域名服务、分布式同步、组服务等。</span></span>）<br /><img style="max-width: 100%; border-top: medium none; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161130235406881" /><br /></span>
<div><span style="color: black">(3. Master</span></div>
<div><span style="color: black">主服务器</span><span style="color: black">Master</span><span style="color: black">主要负责表和</span><span style="color: black">Region</span><span style="color: black">的管理工作：</span></div>
<div><span style="color: black">管理用户对表的增加、删除、修改、查询等操作</span></div>
<div><span style="color: black">实现不同</span><span style="color: black">Region</span><span style="color: black">服务器之间的负载均衡</span></div>
<div><span style="color: black">在</span><span style="color: black">Region</span><span style="color: black">分裂或合并后，负责重新调整</span><span style="color: black">Region</span><span style="color: black">的分布</span></div>
<div><span style="color: black">对发生故障失效的</span><span style="color: black">Region</span><span style="color: black">服务器上的</span><span style="color: black">Region</span><span style="color: black">进行迁移<br /></span>
<div><span style="color: black">(4. Region</span><span style="color: black">服务器</span></div>
<div><span style="color: black">Region</span><span style="color: black">服务器是</span><span style="color: black">HBase</span><span style="color: black">中最核心的模块，负责维护分配给自己的</span><span style="color: black">Region</span><span style="color: black">，并响应用户的读写请求</span></div>2、Region<br /><img style="max-width: 100%; border-top: medium none; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161130235727620" /><br /></div><br />
<div>(1、用户读写数据过程<br /><span style="color: black">用户写入数据时，被分配到相应</span><span style="color: black">Region</span><span style="color: black">服务器去执行</span></div>
<div><span style="color: black">用户数据首先被写入到</span><span style="color: black">MemStore</span><span style="color: black">和</span><span style="color: black">Hlog</span><span style="color: black">中</span></div>
<div><span style="color: black">只有当操作写入</span><span style="color: black">Hlog</span><span style="color: black">之后，</span><span style="color: black">commit()</span><span style="color: black">调用才会将其返回给客户端</span></div>
<div><span style="color: black">当用户读取数据时，</span><span style="color: black">Region</span><span style="color: black">服务器会首先访问</span><span style="color: black">MemStore</span><span style="color: black">缓存，如果找不到，再去磁盘上面的</span><span style="color: black">StoreFile</span><span style="color: black">中寻找</span></div>(2、缓存的刷新<br />
<div><span style="color: black">系统会周期性地把</span><span style="color: black">MemStore</span><span style="color: black">缓存里的内容刷写到磁盘的</span><span style="color: black">StoreFile</span><span style="color: black">文件中，清空缓存，并在</span><span style="color: black">Hlog</span><span style="color: black">里面写入一个标记、<br /></span><span style="color: black">每次刷写都生成一个新的</span><span style="color: black">StoreFile</span><span style="color: black">文件，因此，每个</span><span style="color: black">Store</span><span style="color: black">包含多个</span><span style="color: black">StoreFile</span><span style="color: black">文件</span></div>
<div><br /></div>
<div><span style="color: black">每个</span><span style="color: black">Region</span><span style="color: black">服务器都有一个自己的</span><span style="color: black">HLog</span><span style="color: black">文件，每次启动都检查该文件，确认最近一次执行缓存刷新操作之后是否发生新的写入操作；如果发现更新，则先写入</span><span style="color: black">MemStore</span><span style="color: black">，再刷写到</span><span style="color: black">StoreFile</span><span style="color: black">，最后删除旧的</span><span style="color: black">Hlog</span><span style="color: black">文件，开始为用户提供服务<br /></span>(3、StroreFile的合并<span style="color: black"></span> 
<div><span style="color: black">每次刷写都生成一个新的</span><span style="color: black">StoreFile</span><span style="color: black">，数量太多，影响查找速度</span></div>
<div><span style="color: black">调用</span><span style="color: black">Store.compact()</span><span style="color: black">把多个合并成一个</span></div>
<div><span style="color: black">合并操作比较耗费资源，只有数量达到一个阈值才启动合并</span></div>3、Store工作原理<br />
<div><span style="color: black">Store</span><span style="color: black">是</span><span style="color: black">Region</span><span style="color: black">服务器的核心</span></div>
<div><span style="color: black">多个</span><span style="color: black">StoreFile</span><span style="color: black">合并成一个<br /><span style="color: black"><span style="color: black"><span style="color: black"><span style="color: black">触发分裂操作，</span><span style="color: black">1</span><span style="color: black">个父</span><span style="color: black">Region</span><span style="color: black">被分裂成两个子</span><span style="color: black">Region</span></span></span></span><br /></span></div>
<div><img style="max-width: 100%; border-top: medium none; border-right: medium none; border-bottom: medium none; border-left: medium none; max-height: 100%" alt="" src="http://img.blog.csdn.net/20161201000139345" /><span style="color: black">单个</span><span style="color: black">StoreFile</span><span style="color: black">过大时，又</span></div>4、HLog工作原理<br />
<div><span style="color: black">分布式环境必须要考虑系统出错。</span><span style="color: black">HBase</span><span style="color: black">采用</span><span style="color: black">HLog</span><span style="color: black">保证系统恢复</span></div>
<div><span style="color: black">HBase</span><span style="color: black">系统为每个</span><span style="color: black">Region</span><span style="color: black">服务器配置了一个</span><span style="color: black">HLog</span><span style="color: black">文件，它是一种预写式日志（</span><span style="color: black">WriteAhead Log</span><span style="color: black">）</span></div>
<div><span style="color: black">用户更新数据必须首先写入日志后，才能写入</span><span style="color: black">MemStore</span><span style="color: black">缓存，并且，直到</span><span style="color: black">MemStore</span><span style="color: black">缓存内容对应的日志已经写入磁盘，该缓存内容才能被刷写到磁盘</span></div>
<div><br /><span style="color: black">Zookeeper</span><span style="color: black">会实时监测每个</span><span style="color: black">Region</span><span style="color: black">服务器的状态，当某个</span><span style="color: black">Region</span><span style="color: black">服务器发生故障时，</span><span style="color: black">Zookeeper</span><span style="color: black">会通知</span><span style="color: black">Master</span></div>
<div><span style="color: black">Master</span><span style="color: black">首先会处理该故障</span><span style="color: black">Region</span><span style="color: black">服务器上面遗留的</span><span style="color: black">HLog</span><span style="color: black">文件，这个遗留的</span><span style="color: black">HLog</span><span style="color: black">文件中包含了来自多个</span><span style="color: black">Region</span><span style="color: black">对象的日志记录</span></div>
<div><span style="color: black">系统会根据每条日志记录所属的</span><span style="color: black">Region</span><span style="color: black">对象对</span><span style="color: black">HLog</span><span style="color: black">数据进行拆分，分别放到相应</span><span style="color: black">Region</span><span style="color: black">对象的目录下，然后，再将失效的</span><span style="color: black">Region</span><span style="color: black">重新分配到可用的</span><span style="color: black">Region</span><span style="color: black">服务器中，并把与该</span><span style="color: black">Region</span><span style="color: black">对象相关的</span><span style="color: black">HLog</span><span style="color: black">日志记录也发送给相应的</span><span style="color: black">Region</span><span style="color: black">服务器</span></div>
<div><span style="color: black">Region</span><span style="color: black">服务器领取到分配给自己的</span><span style="color: black">Region</span><span style="color: black">对象以及与之相关的</span><span style="color: black">HLog</span><span style="color: black">日志记录以后，会重新做一遍日志记录中的各种操作，把日志记录中的数据写入到</span><span style="color: black">MemStore</span><span style="color: black">缓存中，然后，刷新到磁盘的</span><span style="color: black">StoreFile</span><span style="color: black">文件中，完成数据恢复</span></div>
<div><span style="color: black">共用日志优点：提高对表的写操作性能；缺点：恢复时需要分拆日志</span></div>五、HBase性能<br />1、<span style="color: black">行键（RowKey）<br /></span></div>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">行键是按照</span><span style="color: black">字典序</span><span style="color: black">存储，因此，设计行键时，要充分利用这个排序特点，将经常一起读取的数据存储到一块，将最近可能会被访问的数据放在一块。</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">举个例子：如果最近写入</span><span style="color: black">HBase</span><span style="color: black">表中的数据是最可能被访问的，可以考虑将时间戳作为行键的一部分，由于是字典序排序，所以可以使用</span><span style="color: black">Long.MAX_VALUE- timestamp</span><span style="color: black">作为行键，这样能保证新写入的数据在读取时可以被快速命中。</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">InMemory：创建表的时候，可以通过</span><span style="color: black">HColumnDescriptor.setInMemory(true)</span><span style="color: black">将表放到</span><span style="color: black">Region</span><span style="color: black">服务器的缓存中，保证在读取的时候被</span><span style="color: black">cache</span><span style="color: black">命中。</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black"></span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">Max Version：创建表的时候，可以通过</span><span style="color: black">HColumnDescriptor.setMaxVersions(int&nbsp;maxVersions)</span><span style="color: black">设置表中数据的最大版本，如果只需要保存最新版本的数据，那么可以设置</span><span style="color: black">setMaxVersions(1)</span><span style="color: black">。</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black"></span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">Time To Live创建表的时候，可以通过</span><span style="color: black">HColumnDescriptor.setTimeToLive(inttimeToLive)</span><span style="color: black">设置表中数据的存储生命期，过期数据将自动被删除，例如如果只需要存储最近两天的数据，那么可以设置</span><span style="color: black">setTimeToLive(2* 24 * 60 * 60)</span><span style="color: black">。</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black"></span></p>
<div><span style="color: black">2、HBaseMaster</span><span style="color: black">默认基于</span><span style="color: black">Web</span><span style="color: black">的</span><span style="color: black">UI</span><span style="color: black">服务端口为</span><span style="color: black">60010</span><span style="color: black">，</span><span style="color: black">HBase region</span><span style="color: black">服务器默认基于</span><span style="color: black">Web</span><span style="color: black">的</span><span style="color: black">UI</span><span style="color: black">服务端口为</span><span style="color: black">60030.</span><span style="color: black">如果</span><span style="color: black">master</span><span style="color: black">运行在名为</span><span style="color: black">master.foo.com</span><span style="color: black">的主机中，</span><span style="color: black">mater</span><span style="color: black">的主页地址就是</span><span style="color: black">http://master.foo.com:60010</span><span style="color: black">，用户可以通过</span><span style="color: black">Web</span><span style="color: black">浏览器输入这个地址查看该页面</span></div><span style="color: black"></span>
<div><span style="color: black">可以查看</span><span style="color: black">HBase</span><span style="color: black">集群的当前状态</span></div>3、<span style="color: black">NoSQL</span><span style="color: black">区别于关系型数据库的一点就是</span><span style="color: black">NoSQL</span><span style="color: black">不使用</span><span style="color: black">SQL</span><span style="color: black">作为查询语言，至于为何在</span><span style="color: black">NoSQL</span><span style="color: black">数据存储</span><span style="color: black">HBase</span><span style="color: black">上提供</span><span style="color: black">SQL</span><span style="color: black">接口</span><br />
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">易使用，减少编码<br /></span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">4、HBase</span><span style="color: black">只有一个针对行健的索引</span></p>
<p style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px"><span style="color: black">访问</span><span style="color: black">HBase</span><span style="color: black">表中的行，只有三种方式：</span></p>
<div><span style="color: black">通过单个行健访问</span></div>
<div><span style="color: black">通过一个行健的区间来访问</span></div>
<div><span style="color: black">全表扫描<br /><br />总结：<br /></span>
<div><span style="color: black">1、HBase</span><span style="color: black">数据库是</span><span style="color: black">BigTable</span><span style="color: black">的开源实现，和</span><span style="color: black">BigTable</span><span style="color: black">一样，支持大规模海量数据，分布式并发数据处理效率极高，易于扩展且支持动态伸缩，适用于廉价设备</span></div>
<div><span style="color: black">2、HBase</span><span style="color: black">可以支持</span><span style="color: black">NativeJava API</span><span style="color: black">、</span><span style="color: black">HBaseShell</span><span style="color: black">、</span><span style="color: black">ThriftGateway</span><span style="color: black">、</span><span style="color: black">Hive</span><span style="color: black">等多种访问接口，可以根据具体应用场合选择相应访问方式</span></div>
<div><span style="color: black">3、HBase</span><span style="color: black">实际上就是一个稀疏、多维、持久化存储的映射表，它采用行键、列键和时间戳进行索引，每个值都是未经解释的字符串。</span></div>
<div><span style="color: black">4、HBase</span><span style="color: black">采用分区存储，一个大的表会被分拆许多个</span><span style="color: black">Region</span><span style="color: black">，这些</span><span style="color: black">Region</span><span style="color: black">会被分发到不同的服务器上实现分布式存储</span></div>
<div><span style="color: black">5、HBase</span><span style="color: black">的系统架构包括客户端、</span><span style="color: black">Zookeeper</span><span style="color: black">服务器、</span><span style="color: black">Master</span><span style="color: black">主服务器、</span><span style="color: black">Region</span><span style="color: black">服务器。客户端包含访问</span><span style="color: black">HBase</span><span style="color: black">的接口；</span><span style="color: black">Zookeeper</span><span style="color: black">服务器负责提供稳定可靠的协同服务；</span><span style="color: black">Master</span><span style="color: black">主服务器主要负责表和</span><span style="color: black">Region</span><span style="color: black">的管理工作；</span><span style="color: black">Region</span><span style="color: black">服务器负责维护分配给自己的</span><span style="color: black">Region</span><span style="color: black">，并响应用户的读写请求</span></div></div></div></div><img src ="http://www.blogjava.net/tjyhy590/aggbug/432671.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-07-19 22:24 <a href="http://www.blogjava.net/tjyhy590/archive/2017/07/19/432671.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在python中获取mac和ip地址</title><link>http://www.blogjava.net/tjyhy590/archive/2017/05/15/432530.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Mon, 15 May 2017 15:26:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/05/15/432530.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432530.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/05/15/432530.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432530.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432530.html</trackback:ping><description><![CDATA[<span style="white-space: normal; word-spacing: 0px; text-transform: none; float: none; color: rgb(0,0,0); text-align: justify; font: 15px/26px 'Microsoft Yahei', 'Helvetica Neue', Helvetica, Arial, sans-serif; widows: 1; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">python 获得本机MAC地址：<br /></span><font face="Verdana">import uuid<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def get_mac_address():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mac=uuid.UUID(int=uuid.getnode()).hex[-12:]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ":".join([mac[e:e+2] for e in range(0,11,2)])<br /><br /><br /><span style="white-space: normal; word-spacing: 0px; text-transform: none; float: none; color: rgb(0,0,0); text-align: justify; font: 15px/26px 'Microsoft Yahei', 'Helvetica Neue', Helvetica, Arial, sans-serif; widows: 1; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">python获取IP的方法：使用socket<br /></span><br />import socket</font><br />myname=socket.getfqdn(socket.gethostname( ))<br />&nbsp;&nbsp;&nbsp;&nbsp;myaddr=socket.gethostbyname(myname)<br />&nbsp;&nbsp;&nbsp;&nbsp;print(myname)<br />&nbsp;&nbsp;&nbsp;&nbsp;print(myaddr)<br /><br /><img src ="http://www.blogjava.net/tjyhy590/aggbug/432530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-05-15 23:26 <a href="http://www.blogjava.net/tjyhy590/archive/2017/05/15/432530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring—Quartz定时调度CronTrigger时间配置格式说明与实例</title><link>http://www.blogjava.net/tjyhy590/archive/2017/04/29/432492.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Sat, 29 Apr 2017 04:01:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2017/04/29/432492.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/432492.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2017/04/29/432492.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/432492.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/432492.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: Arial; line-height: 26px;"><a href="http://lib.csdn.net/base/javaee" title="Java EE知识库" target="_blank" style="color: #df3434; text-decoration: none; font-weight: bold;">spring</a>中使用Quartz时 时间配置例子：</p><p style="color: #333333; font-family: Arial; line-height: 26px;">&lt;!-- 定义调用对象和调用对象的方法 end &nbsp; --&gt;<br />&lt;!-- 定义调用时间 begin --&gt;<br />&lt;bean id="realweatherTime" class="org.springframework.scheduling.quartz.CronTriggerBean"&gt;<br />&lt;property name="jobDetail"&gt;<br />&lt;ref bean="realweatherTask" /&gt;<br />&lt;/property&gt;<br />&lt;property name="cronExpression"&gt;<br />&lt;value&gt;0 10/30 * * * ?&lt;/value&gt;&lt;!-- 表示每小时的10，40时执行任务 --&gt;<br />&lt;/property&gt;<br />&lt;/bean&gt;<br />&lt;!-- 定义调用时间 end &nbsp; --&gt;<br /></p><p style="color: #333333; font-family: Arial; line-height: 26px;"><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px;">&lt;!-- 定义调用对象和调用对象的方法 end &nbsp; --&gt;<br />&lt;!-- 定义调用时间 begin --&gt;<br />&lt;bean id="weatherTime" class="org.springframework.scheduling.quartz.CronTriggerBean"&gt;<br />&lt;property name="jobDetail"&gt;<br />&lt;ref bean="weatherTask" /&gt;<br />&lt;/property&gt;<br />&lt;property name="cronExpression"&gt;<br /><span style="white-space: pre;">&lt;!--&nbsp; </span>&lt;value&gt;0 30 8,13 * * ?&lt;/value&gt; &nbsp;--&gt;&lt;!-- 表示每天的8:30和13:30时执行任务 --&gt;<br />&lt;value&gt;0 0,30 0-23 * * ?&lt;/value&gt;&lt;!---表示每天从0-23时中每时的整点或半点执行任务-&gt;<br />&lt;/property&gt;<br />&lt;/bean&gt;<br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&lt;!-- 定义调用时间 end &nbsp; --&gt;<span style="font-family: 宋体;"><span style="font-size: 12px;">1、</span><span style="font-stretch: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp;</span></span><span style="font-size: 12px;"><span style="font-family: 宋体;">&nbsp;CronTrigger</span><span style="font-family: 宋体;">时间格式配置说明</span></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-indent: 21.1pt; background-color: #ffffff;"><span style="font-family: 宋体;"><strong><span style="font-size: 10.5pt;">CronTrigger</span><span style="font-size: 10.5pt;">配置格式</span></strong><span style="font-size: 10.5pt;">:</span></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-indent: 21pt; background-color: #ffffff;"><span style="font-size: 10.5pt;"><span style="font-family: 宋体;">格式: [秒] [分] [小时] [日] [月] [周] [年]</span></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-indent: 21pt; background-color: #ffffff;"><span style="font-size: 10.5pt;"><span style="font-family: 宋体;"></span></span></p><table "="" border="0" cellpadding="0" style="color: #333333; font-family: Arial; font-size: 14px; line-height: 26px; margin: auto auto auto 1.5pt; width: 506px; background-color: #ffffff;"><tbody><tr><td width="47" style="padding: 1.5pt; border: #e2e2e2; width: 35.25pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">序号</span></span></p></td><td width="58" style="padding: 1.5pt; border: #e2e2e2; width: 43.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">说明</span></span></p></td><td width="94" style="padding: 1.5pt; border: #e2e2e2; width: 70.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">是否必填</span></span></p></td><td width="166" style="padding: 1.5pt; border: #e2e2e2; width: 124.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">允许填写的值</span></span></p></td><td width="129" style="padding: 1.5pt; border: #e2e2e2; width: 96.75pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">允许的通配符</span></span></p></td></tr><tr><td width="47" style="padding: 1.5pt; border: #e2e2e2; width: 35.25pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">1</span></span></p></td><td width="58" style="padding: 1.5pt; border: #e2e2e2; width: 43.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">秒</span></span></p></td><td width="94" style="padding: 1.5pt; border: #e2e2e2; width: 70.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">是</span></span></p></td><td width="166" style="padding: 1.5pt; border: #e2e2e2; width: 124.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">0-59&nbsp;</span></span></p></td><td width="129" style="padding: 1.5pt; border: #e2e2e2; width: 96.75pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">, - * /</span></span></p></td></tr><tr><td width="47" style="padding: 1.5pt; border: #e2e2e2; width: 35.25pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">2</span></span></p></td><td width="58" style="padding: 1.5pt; border: #e2e2e2; width: 43.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">分</span></span></p></td><td width="94" style="padding: 1.5pt; border: #e2e2e2; width: 70.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">是</span></span></p></td><td width="166" style="padding: 1.5pt; border: #e2e2e2; width: 124.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">0-59</span></span></p></td><td width="129" style="padding: 1.5pt; border: #e2e2e2; width: 96.75pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">, - * /</span></span></p></td></tr><tr><td width="47" style="padding: 1.5pt; border: #e2e2e2; width: 35.25pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">3</span></span></p></td><td width="58" style="padding: 1.5pt; border: #e2e2e2; width: 43.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">小时</span></span></p></td><td width="94" style="padding: 1.5pt; border: #e2e2e2; width: 70.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">是</span></span></p></td><td width="166" style="padding: 1.5pt; border: #e2e2e2; width: 124.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">0-23</span></span></p></td><td width="129" style="padding: 1.5pt; border: #e2e2e2; width: 96.75pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">, - * /</span></span></p></td></tr><tr><td width="47" style="padding: 1.5pt; border: #e2e2e2; width: 35.25pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">4</span></span></p></td><td width="58" style="padding: 1.5pt; border: #e2e2e2; width: 43.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">日</span></span></p></td><td width="94" style="padding: 1.5pt; border: #e2e2e2; width: 70.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">是</span></span></p></td><td width="166" style="padding: 1.5pt; border: #e2e2e2; width: 124.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">1-31</span></span></p></td><td width="129" style="padding: 1.5pt; border: #e2e2e2; width: 96.75pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">, - * ? / L W</span></span></p></td></tr><tr><td width="47" style="padding: 1.5pt; border: #e2e2e2; width: 35.25pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">5</span></span></p></td><td width="58" style="padding: 1.5pt; border: #e2e2e2; width: 43.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">月</span></span></p></td><td width="94" style="padding: 1.5pt; border: #e2e2e2; width: 70.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">是</span></span></p></td><td width="166" style="padding: 1.5pt; border: #e2e2e2; width: 124.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">1-12 or JAN-DEC</span></span></p></td><td width="129" style="padding: 1.5pt; border: #e2e2e2; width: 96.75pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">, - * /</span></span></p></td></tr><tr><td width="47" style="padding: 1.5pt; border: #e2e2e2; width: 35.25pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">6</span></span></p></td><td width="58" style="padding: 1.5pt; border: #e2e2e2; width: 43.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">周</span></span></p></td><td width="94" style="padding: 1.5pt; border: #e2e2e2; width: 70.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">是</span></span></p></td><td width="166" style="padding: 1.5pt; border: #e2e2e2; width: 124.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">1-7 or SUN-SAT</span></span></p></td><td width="129" style="padding: 1.5pt; border: #e2e2e2; width: 96.75pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">, - * ? / L #</span></span></p></td></tr><tr><td width="47" style="padding: 1.5pt; border: #e2e2e2; width: 35.25pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">7</span></span></p></td><td width="58" style="padding: 1.5pt; border: #e2e2e2; width: 43.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">年</span></span></p></td><td width="94" style="padding: 1.5pt; border: #e2e2e2; width: 70.5pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">否</span></span></p></td><td width="166" style="padding: 1.5pt; border: #e2e2e2; width: 124.5pt; background-color: transparent;"><p align="left"><span style="font-size: 12px;"><span style="font-family: 宋体;">empty&nbsp;</span><span style="font-family: 宋体;">或&nbsp;1970-2099</span></span></p></td><td width="129" style="padding: 1.5pt; border: #e2e2e2; width: 96.75pt; background-color: transparent;"><p align="left"><span style="font-family: 宋体;"><span style="font-size: 12px;">, - * /</span></span></p></td></tr></tbody></table><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-indent: 21pt; background-color: #ffffff;"><span style="font-size: 10.5pt;"></span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; text-indent: 21.1pt; background-color: #ffffff;"><span style="font-size: 12px;"><strong><span style="font-family: 宋体;">通配符说明</span></strong><span style="font-family: 宋体;">:</span></span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; margin: 0cm 0cm 0pt 31.5pt; background-color: #ffffff;"><strong><span style="font-family: 宋体; color: red;"><span style="font-size: 12px;">*&nbsp;</span></span></strong><span style="font-family: 宋体;"><span style="font-size: 12px;">：表示所有值.&nbsp;例如:在分的字段上设置&nbsp;"*",表示每一分钟都会触发。</span><br /><span style="font-size: 12px;"><strong><span style="color: red;">?</span></strong>&nbsp;</span></span><span style="font-size: 12px;">：表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作，但不关心是周几，所以需要周位置的那个字段设置为"?"&nbsp;具体设置为</span><span style="font-size: 12px;">&nbsp;0 0 0 10&nbsp;<span style="color: red;">*&nbsp;?<br /><strong>-</strong>&nbsp;</span>：表示区间。例如 在小时上设置&nbsp;"10-12",表示&nbsp;10,11,12点都会触发。</span><br /><span style="font-size: 12px;"><strong><span style="color: red;">,</span></strong>&nbsp;</span><span style="font-size: 12px;">：表示指定多个值，例如在周字段上设置&nbsp;"MON,WED,FRI"&nbsp;表示周一，周三和周五触发</span><br /><strong><span style="color: red;"><span style="font-size: 12px;">/&nbsp;</span></span></strong><span style="font-size: 12px;">：用于递增触发。如在秒上面设置"5/15"&nbsp;表示从5秒开始，每增15秒触发(5,20,35,50)。 在月字段上设置'1/3'所示每月1号开始，每隔三天触发一次。</span><br /><span style="font-size: 12px;"><strong><span style="color: red;">L</span></strong>&nbsp;</span><span style="font-size: 12px;">：表示最后的意思。在日字段设置上，表示当月的最后一天(依据当前月份，如果是二月还会依据是否是润年[leap]),&nbsp;在周字段上表示星期六，相当于"7"或"SAT"。如果在"L"前加上数字，则表示该数据的最后一个。</span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; margin: 0cm 0cm 0pt 31.5pt; text-indent: 25.7pt; background-color: #ffffff;"><span style="font-family: 宋体;"><span style="font-size: 12px;">例如在周字段上设置"6L"这样的格式,则表示&#8220;本月最后一个星期五"</span></span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; margin: 0cm 0cm 0pt 31.5pt; background-color: #ffffff;"><span style="font-size: 12px;"><strong><span style="font-family: 宋体; color: red;">W</span></strong>&nbsp;<span style="font-family: 宋体;">：表示离指定日期的最近那个工作日(周一至周五).&nbsp;例如在日字段上设置"15W"，表示离每月15号最近的那个工作日触发。如果15号正好是周六，则找最近的周五(14号)触发,&nbsp;如果15号是周未，则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五)，则就在该天触发。如果指定格式为&nbsp;"1W",它则表示每月1号往后最近的工作日触发。如果1号正是周六，则将在3号下周一触发。(注，"W"前只能设置具体的数字,不允许区间"-").</span></span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; margin: 0cm 0cm 0pt 31.5pt; text-indent: 21pt; background-color: #ffffff;"><span style="font-size: 12px;"><span style="font-family: 宋体;">'L'</span><span style="font-family: 宋体;">和&nbsp;'W'可以一组合使用。如果在日字段上设置"LW",则表示在本月的最后一个工作日触发</span></span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; margin: 0cm 0cm 0pt 31.5pt; text-indent: 21pt; background-color: #ffffff;"><span style="font-family: 宋体;">&nbsp;</span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; margin: 0cm 0cm 0pt 31.5pt; background-color: #ffffff;"><span style="font-size: 12px;"><strong><span style="font-family: 宋体; color: red;">#</span></strong>&nbsp;<span style="font-family: 宋体;">：序号(表示每月的第几周星期几)，例如在周字段上设置"6#3"表示在每月的第三个周星期六.注意如果指定"6#5",正好第五周没有星期六，则不会触发该配置(用在母亲节和父亲节再合适不过了)</span></span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; margin: 0cm 0cm 0pt 31.5pt; text-indent: 21pt; background-color: #ffffff;"><span style="font-family: 宋体;"><span style="font-size: 12px;">周字段的设置，若使用英文字母是不区分大小写的&nbsp;MON&nbsp;与mon相同.</span></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong><span style="font-family: 宋体;"><span style="font-size: 12px;">常用示例:</span></span></strong></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-indent: 21pt; background-color: #ffffff;"><span style="font-size: 10.5pt;"><span style="font-family: 宋体;">格式: [秒] [分] [小时] [日] [月] [周] [年]</span></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-family: 宋体;"><span style="font-size: 12px;">0 0 12 * * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-family: 宋体;"><span style="font-size: 12px;">每天12点触发</span><span style="font-size: 12px;">&nbsp;<br />0 15 10 ? * *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每天10点15分触发</span><span style="font-size: 12px;">&nbsp;<br />0 15 10 * * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每天10点15分触发</span><span style="font-size: 12px;">&nbsp;&nbsp;<br />0 15 10 * * ? *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每天10点15分触发</span><span style="font-size: 12px;">&nbsp;&nbsp;<br />0 15 10 * * ? 2005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2005年每天10点15分触发</span><span style="font-size: 12px;">&nbsp;<br />0 * 14 * * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每天下午的&nbsp;2点到2点59分每分触发</span><span style="font-size: 12px;">&nbsp;<br />0 0/5 14 * * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每天下午的&nbsp;2点到2点59分(整点开始，每隔5分触发</span><span style="font-size: 12px;">)&nbsp;&nbsp;<br />0 0/5 14,18 * * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每天下午的&nbsp;18点到18点59分(整点开始，每隔5分触发)</span></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-family: 宋体;"><span style="font-size: 12px;">0 0-5 14 * * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-family: 宋体;"><span style="font-size: 12px;">每天下午的&nbsp;2点到2点05分每分触发</span><span style="font-size: 12px;">&nbsp;<br />0 10,44 14 ? 3 WED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3月分每周三下午的&nbsp;2点10分和2点44分触发</span><span style="font-size: 12px;">&nbsp;<br />0 15 10 ? * MON-FRI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从周一到周五每天上午的10点15分触发</span><span style="font-size: 12px;">&nbsp;<br />0 15 10 15 * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每月15号上午10点15分触发</span><span style="font-size: 12px;">&nbsp;<br />0 15 10 L * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每月最后一天的10点15分触发</span><span style="font-size: 12px;">&nbsp;<br />0 15 10 ? * 6L&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每月最后一周的星期五的10点15分触发</span><span style="font-size: 12px;">&nbsp;<br />0 15 10 ? * 6L 2002-2005&nbsp;&nbsp;从2002年到2005年每月最后一周的星期五的10点15分触发</span></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-family: 宋体;"><span style="font-size: 12px;">0 15 10 ? * 6#3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-family: 宋体;"><span style="font-size: 12px;">每月的第三周的星期五开始触发</span><span style="font-size: 12px;">&nbsp;<br />0 0 12 1/5 * ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每月的第一个中午开始每隔5天触发一次</span><span style="font-size: 12px;">&nbsp;<br />0 11 11 11 11 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每年的11月11号&nbsp;11点11分触发(光棍节)<br /><br /></span></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a href="http://lib.csdn.net/base/javaee" class="replace_word" title="Java EE知识库" target="_blank" style="color: #df3434; text-decoration: none; font-weight: bold;">spring</a>中使用Quartz时 时间配置例子：</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="white-space: pre;"></span>&lt;!-- 定义调用对象和调用对象的方法 end &nbsp; --&gt;<br /><span style="white-space: pre;"></span>&lt;!-- 定义调用时间 begin --&gt;<br /><span style="white-space: pre;"></span>&lt;bean id="realweatherTime" class="org.springframework.scheduling.quartz.CronTriggerBean"&gt;<br /><span style="white-space: pre;"></span>&lt;property name="jobDetail"&gt;<br /><span style="white-space: pre;"></span>&lt;ref bean="realweatherTask" /&gt;<br /><span style="white-space: pre;"></span>&lt;/property&gt;<br /><span style="white-space: pre;"></span>&lt;property name="cronExpression"&gt;<br /><span style="white-space: pre;"></span>&lt;value&gt;0 10/30 * * * ?&lt;/value&gt;&lt;!-- 表示每小时的10，40时执行任务 --&gt;<br /><span style="white-space: pre;"></span>&lt;/property&gt;<br /><span style="white-space: pre;"></span>&lt;/bean&gt;<br /><span style="white-space: pre;"></span>&lt;!-- 定义调用时间 end &nbsp; --&gt;<br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&lt;!-- 定义调用对象和调用对象的方法 end &nbsp; --&gt;<br /><span style="white-space: pre;"></span>&lt;!-- 定义调用时间 begin --&gt;<br /><span style="white-space: pre;"></span>&lt;bean id="weatherTime" class="org.springframework.scheduling.quartz.CronTriggerBean"&gt;<br /><span style="white-space: pre;"></span>&lt;property name="jobDetail"&gt;<br /><span style="white-space: pre;"></span>&lt;ref bean="weatherTask" /&gt;<br /><span style="white-space: pre;"></span>&lt;/property&gt;<br /><span style="white-space: pre;"></span>&lt;property name="cronExpression"&gt;<br /><span style="white-space: pre;">&lt;!--&nbsp; </span>&lt;value&gt;0 30 8,13 * * ?&lt;/value&gt; &nbsp;--&gt;&lt;!-- 表示每天的8:30和13:30时执行任务 --&gt;<br /><span style="white-space: pre;"></span>&lt;value&gt;0 0,30 0-23 * * ?&lt;/value&gt;&lt;!---表示每天从0-23时中每时的整点或半点执行任务-&gt;<br /><span style="white-space: pre;"></span>&lt;/property&gt;<br /><span style="white-space: pre;"></span>&lt;/bean&gt;<br /><span style="white-space: pre;"></span>&lt;!-- 定义调用时间 end &nbsp; --&gt;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-family: 宋体;"><span style="font-size: 12px;"><br /></span></span></p><img src ="http://www.blogjava.net/tjyhy590/aggbug/432492.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2017-04-29 12:01 <a href="http://www.blogjava.net/tjyhy590/archive/2017/04/29/432492.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>前端内容展示操作</title><link>http://www.blogjava.net/tjyhy590/archive/2016/03/09/429579.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Wed, 09 Mar 2016 03:36:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2016/03/09/429579.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/429579.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2016/03/09/429579.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/429579.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/429579.html</trackback:ping><description><![CDATA[1.有时表格内容太多，只显示部分，其余部分已省略号表示，用css处理如下：<br /><div>.template td{</div><div>&nbsp; &nbsp; word-break:keep-all;/* 不换行 */</div><div>&nbsp; &nbsp; white-space:nowrap;/* 不换行 */</div><div>&nbsp; &nbsp; overflow:hidden;/* 内容超出宽度时隐藏超出部分的内容 */</div><div>&nbsp; &nbsp; text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/</div><div>}</div><br />template 是该表单所在的table class属性。<br /><br /><img src ="http://www.blogjava.net/tjyhy590/aggbug/429579.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2016-03-09 11:36 <a href="http://www.blogjava.net/tjyhy590/archive/2016/03/09/429579.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>js 金额 用逗号 隔开数字格式化</title><link>http://www.blogjava.net/tjyhy590/archive/2015/09/27/427511.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Sun, 27 Sep 2015 02:23:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2015/09/27/427511.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/427511.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2015/09/27/427511.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/427511.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/427511.html</trackback:ping><description><![CDATA[<div>代码如下： <br /> <div>引用</div> <div><br />function fmoney(s, n)&nbsp;&nbsp; <br />{&nbsp;&nbsp; <br />&nbsp;&nbsp; n = n &gt; 0 &amp;&amp; n &lt;= 20 ? n : 2;&nbsp;&nbsp; <br />&nbsp;&nbsp; s = parseFloat((s + "").replace(/[^\d\.-]/g, "")).toFixed(n) + "";&nbsp;&nbsp; <br />&nbsp;&nbsp; var l = s.split(".")[0].split("").reverse(),&nbsp;&nbsp; <br />&nbsp;&nbsp; r = s.split(".")[1];&nbsp;&nbsp; <br />&nbsp;&nbsp; t = "";&nbsp;&nbsp; <br />&nbsp;&nbsp; for(i = 0; i &lt; l.length; i ++ )&nbsp;&nbsp; <br />&nbsp;&nbsp; {&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t += l[i] + ((i + 1) % 3 == 0 &amp;&amp; (i + 1) != l.length ? "," : "");&nbsp;&nbsp; <br />&nbsp;&nbsp; }&nbsp;&nbsp; <br />&nbsp;&nbsp; return t.split("").reverse().join("") + "." + r;&nbsp;&nbsp; <br />}</div><br /><br />调用：fmoney("12345.675910", 3)，返回12,345.676 <br /><br />还原函数： <br /> <div>引用</div> <div><br />function rmoney(s)&nbsp;&nbsp; <br />{&nbsp;&nbsp; <br />&nbsp;&nbsp; return parseFloat(s.replace(/[^\d\.-]/g, ""));&nbsp;&nbsp; <br />}</div><br /><br />示例（可保存一下代码为html文件，运行查看效果）： <br /> <div>引用</div> <br />&lt;SCRIPT&gt;&nbsp;&nbsp; <br />function fmoney(s, n)&nbsp;&nbsp; <br />{&nbsp;&nbsp; <br />&nbsp;&nbsp; n = n &gt; 0 &amp;&amp; n &lt;= 20 ? n : 2;&nbsp;&nbsp; <br />&nbsp;&nbsp; s = parseFloat((s + "").replace(/[^\d\.-]/g, "")).toFixed(n) + "";&nbsp;&nbsp; <br />&nbsp;&nbsp; var l = s.split(".")[0].split("").reverse(),&nbsp;&nbsp; <br />&nbsp;&nbsp; r = s.split(".")[1];&nbsp;&nbsp; <br />&nbsp;&nbsp; t = "";&nbsp;&nbsp; <br />&nbsp;&nbsp; for(i = 0; i &lt; l.length; i ++ )&nbsp;&nbsp; <br />&nbsp;&nbsp; {&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t += l[i] + ((i + 1) % 3 == 0 &amp;&amp; (i + 1) != l.length ? "," : "");&nbsp;&nbsp; <br />&nbsp;&nbsp; }&nbsp;&nbsp; <br />&nbsp;&nbsp; return t.split("").reverse().join("") + "." + r;&nbsp;&nbsp; <br />}&nbsp;&nbsp; <br />function rmoney(s)&nbsp;&nbsp; <br />{&nbsp;&nbsp; <br />&nbsp;&nbsp; return parseFloat(s.replace(/[^\d\.-]/g, ""));&nbsp;&nbsp; <br />}&nbsp;&nbsp; <br />function g(id)&nbsp;&nbsp; <br />{&nbsp;&nbsp; <br />&nbsp;&nbsp; return document.getElementById(id);&nbsp;&nbsp; <br />}&nbsp;&nbsp; <br />window.onload = function()&nbsp;&nbsp; <br />{&nbsp;&nbsp; <br />&nbsp;&nbsp; var num,&nbsp;&nbsp; <br />&nbsp;&nbsp; txt = g("txt"),&nbsp;&nbsp; <br />&nbsp;&nbsp; txt2 = g("txt2"),&nbsp;&nbsp; <br />&nbsp;&nbsp; btn = g("btn"),&nbsp;&nbsp; <br />&nbsp;&nbsp; btn2 = g("btn2"),&nbsp;&nbsp; <br />&nbsp;&nbsp; span = g("span");&nbsp;&nbsp; <br />&nbsp;&nbsp; btn.onclick = function()&nbsp;&nbsp; <br />&nbsp;&nbsp; {&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num = parseInt(g("num").value);&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txt.value = fmoney(txt.value, num);&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txt2.value = fmoney(txt2.value, num);&nbsp;&nbsp; <br />&nbsp;&nbsp; }&nbsp;&nbsp; <br />&nbsp;&nbsp; ;&nbsp;&nbsp; <br />&nbsp;&nbsp; btn2.onclick = function()&nbsp;&nbsp; <br />&nbsp;&nbsp; {&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num = parseInt(g("num").value);&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; span.innerHTML = "=" + fmoney(rmoney(txt.value) + rmoney(txt2.value), num);&nbsp;&nbsp; <br />&nbsp;&nbsp; }&nbsp;&nbsp; <br />&nbsp;&nbsp; ;&nbsp;&nbsp; <br />}&nbsp;&nbsp; <br />;&nbsp;&nbsp; <br />&lt;/SCRIPT&gt;&nbsp;&nbsp; <br />小数点位数：&nbsp;&nbsp; <br />&lt;select id="num"&gt;&nbsp;&nbsp; <br />&lt;option value="2"&gt;2&lt;/option&gt;&nbsp;&nbsp; <br />&lt;option value="3"&gt;3&lt;/option&gt;&nbsp;&nbsp; <br />&lt;option value="4"&gt;4&lt;/option&gt;&nbsp;&nbsp; <br />&lt;option value="5"&gt;5&lt;/option&gt;&nbsp;&nbsp; <br />&lt;/select&gt;&nbsp;&nbsp; <br />&lt;input type="text" id="txt" value="12345.675910"&gt; +&nbsp;&nbsp; <br />&lt;input type="text" id="txt2" value="1223"&gt; &lt;span id="span"&gt;&lt;/span&gt;&nbsp;&nbsp; <br />&lt;br&gt;&nbsp;&nbsp; <br />&lt;input type="button" id="btn" value="<strong style="background-color: #ff66ff; color: black">格式化</strong>"&gt;&nbsp;&nbsp; <br />&lt;input type="button" id="btn2" value="相加"&gt; </div><img src ="http://www.blogjava.net/tjyhy590/aggbug/427511.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2015-09-27 10:23 <a href="http://www.blogjava.net/tjyhy590/archive/2015/09/27/427511.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BigDecimal用法详解</title><link>http://www.blogjava.net/tjyhy590/archive/2015/08/22/426949.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Sat, 22 Aug 2015 04:56:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2015/08/22/426949.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/426949.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2015/08/22/426949.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/426949.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/426949.html</trackback:ping><description><![CDATA[<p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"><strong>一、简介</strong><br />Java在java.math包中提供的API类BigDecimal，用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中，需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算，在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象，我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算，而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法，专门用来创建对象，特别是带有参数的对象。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"><br /><strong>二、构造器描述</strong>&nbsp;<br />BigDecimal(int) &nbsp; &nbsp; &nbsp; 创建一个具有参数所指定整数值的对象。&nbsp;<br />BigDecimal(double) 创建一个具有参数所指定双精度值的对象。&nbsp;<br />BigDecimal(long) &nbsp; &nbsp;创建一个具有参数所指定长整数值的对象。&nbsp;<br />BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"><strong>三、方法描述</strong>&nbsp;<br />add(BigDecimal) &nbsp; &nbsp; &nbsp; &nbsp;BigDecimal对象中的值相加，然后返回这个对象。&nbsp;<br />subtract(BigDecimal) BigDecimal对象中的值相减，然后返回这个对象。&nbsp;<br />multiply(BigDecimal) &nbsp;BigDecimal对象中的值相乘，然后返回这个对象。&nbsp;<br />divide(BigDecimal) &nbsp; &nbsp; BigDecimal对象中的值相除，然后返回这个对象。&nbsp;<br />toString() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;将BigDecimal对象的数值转换成字符串。&nbsp;<br />doubleValue() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;将BigDecimal对象中的值以双精度数返回。&nbsp;<br />floatValue() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 将BigDecimal对象中的值以单精度数返回。&nbsp;<br />longValue() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 将BigDecimal对象中的值以长整数返回。&nbsp;<br />intValue() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 将BigDecimal对象中的值以整数返回。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"><strong>四、格式化及例子</strong><br />由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数，可以利用BigDecimal对超出16位有效数字的货币值，百分值，以及一般数值进行格式化控制。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">以利用BigDecimal对货币和百分比格式化为例。首先，创建BigDecimal对象，进行BigDecimal的算术运算后，分别建立对货币和百分比格式化的引用，最后利用BigDecimal对象作为format()方法的参数，输出其格式化的货币值和百分比。</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">void</span><span style="line-height: 1.5 !important;"> main(String[] args) {     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">NumberFormat currency </span>= NumberFormat.getCurrencyInstance(); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">建立货币格式化引用 </span>     <br />&nbsp;&nbsp;&nbsp;&nbsp;NumberFormat percent = NumberFormat.getPercentInstance();  <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">建立百分比格式化引用 </span>     <br />&nbsp;&nbsp;&nbsp;&nbsp;percent.setMaximumFractionDigits(3); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">百分比小数点最多3位 </span> <span style="line-height: 1.5 !important;">         <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">BigDecimal loanAmount </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span> BigDecimal("15000.48"); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">贷款金额</span>     <br />&nbsp;&nbsp;&nbsp;&nbsp;BigDecimal interestRate = <span style="color: #0000ff; line-height: 1.5 !important;">new</span> BigDecimal("0.008"); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">利率   </span>     <br />&nbsp;&nbsp;&nbsp;&nbsp;BigDecimal interest = loanAmount.multiply(interestRate); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">相乘</span> <span style="line-height: 1.5 !important;">     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">System.out.println(</span>"贷款金额:\t" +<span style="line-height: 1.5 !important;"> currency.format(loanAmount));      <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">System.out.println(</span>"利率:\t" +<span style="line-height: 1.5 !important;"> percent.format(interestRate));      <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">System.out.println(</span>"利息:\t" +<span style="line-height: 1.5 !important;"> currency.format(interest));  }</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">运行结果如下：</p><div style="margin: 5px 0px; font-size: 12px !important;"><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;">贷款金额:    ￥15,000.48<span style="line-height: 1.5 !important;"> <br />利率:    </span>0.8%<span style="line-height: 1.5 !important;"> <br />利息:    ￥</span>120.00</pre></div><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"><strong>五、BigDecimal比较</strong><br />BigDecimal是通过使用compareTo(BigDecimal)来比较的，具体比较情况如下：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">void</span><span style="line-height: 1.5 !important;"> main(String[] args) {     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">BigDecimal a </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span> BigDecimal("1"<span style="line-height: 1.5 !important;">);     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">BigDecimal b </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span> BigDecimal("2"<span style="line-height: 1.5 !important;">);     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">BigDecimal c </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span> BigDecimal("1"<span style="line-height: 1.5 !important;">);     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; line-height: 1.5 !important;">int</span> result1 =<span style="line-height: 1.5 !important;"> a.compareTo(b);     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; line-height: 1.5 !important;">int</span> result2 =<span style="line-height: 1.5 !important;"> a.compareTo(c);     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; line-height: 1.5 !important;">int</span> result3 =<span style="line-height: 1.5 !important;"> b.compareTo(a);     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">System.out.println(result1);     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">System.out.println(result2);     <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5 !important;">System.out.println(result3);      <br />}</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">打印结果是：-1、0、1，即左边比右边数大，返回1，相等返回0，比右边小返回-1。<br /><span style="line-height: 1.5; color: #ff0000;">注意不能使用equals方法来比较大小。</span></p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"><span style="line-height: 1.5; color: #0000ff;">使用BigDecimal的坏处是性能比double和float差，在处理庞大，复杂的运算时尤为明显，因根据实际需求决定使用哪种类型。</span></p><img src ="http://www.blogjava.net/tjyhy590/aggbug/426949.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2015-08-22 12:56 <a href="http://www.blogjava.net/tjyhy590/archive/2015/08/22/426949.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle列转行</title><link>http://www.blogjava.net/tjyhy590/archive/2015/07/27/426452.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Mon, 27 Jul 2015 15:52:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2015/07/27/426452.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/426452.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2015/07/27/426452.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/426452.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/426452.html</trackback:ping><description><![CDATA[<div style="word-spacing: 0px; font: 16px/26px 宋体, Arial; text-transform: none; color: rgb(102,102,102); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; word-wrap: break-word; orphans: auto; widows: auto; webkit-text-stroke-width: 0px">如果你只是寻求多行转换成一列，比如把同一个id的某个字段col变成一行数据库，把多个col用逗号链接起来。下面几个SQL可以立竿见影。</div>
<div style="word-spacing: 0px; font: 16px/26px 宋体, Arial; text-transform: none; color: rgb(102,102,102); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; word-wrap: break-word; orphans: auto; widows: auto; webkit-text-stroke-width: 0px">
<div style="word-wrap: break-word">《1》最简短的方式，使用WMSYS.WM_CONCAT：</div>
<div style="word-wrap: break-word">SELECT id, REPLACE(wmsys.wm_concat(col), ',', '/') str<br style="word-wrap: break-word" />FROM Table1<br style="word-wrap: break-word" />GROUP BY id;</div>
<div style="word-wrap: break-word">
<div style="word-wrap: break-word">《2》使用sys_connect_by_path：</div>
<div style="word-wrap: break-word">SELECT t.id id, MAX(substr(sys_connect_by_path(t.col, ','), 2)) str<br style="word-wrap: break-word" />FROM (SELECT id, col, row_number() over(PARTITION BY id ORDER BY col) rn<br style="word-wrap: break-word" />FROM Table1) t<br style="word-wrap: break-word" />START WITH rn = 1<br style="word-wrap: break-word" />CONNECT BY rn = PRIOR rn + 1<br style="word-wrap: break-word" />AND id = PRIOR id<br style="word-wrap: break-word" />GROUP BY t.id;</div>
<div style="word-wrap: break-word">或者</div>
<div style="word-wrap: break-word">SELECT t.id id, substr(sys_connect_by_path(t.col, ','), 2) str<br style="word-wrap: break-word" />FROM (SELECT id, col, row_number() over(PARTITION BY id ORDER BY col) rn<br style="word-wrap: break-word" />FROM Table1) t<br style="word-wrap: break-word" />WHERE connect_by_isleaf = 1<br style="word-wrap: break-word" />START WITH rn = 1<br style="word-wrap: break-word" />CONNECT BY rn = PRIOR rn + 1<br style="word-wrap: break-word" />AND id = PRIOR id;</div></div></div>
<div style="word-spacing: 0px; font: 16px/26px 宋体, Arial; text-transform: none; color: rgb(102,102,102); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; word-wrap: break-word; orphans: auto; widows: auto; webkit-text-stroke-width: 0px">
<div style="word-wrap: break-word">《3》使用MODEL：</div>
<div style="word-wrap: break-word">SELECT id, substr(str, 2) str FROM Table1<br style="word-wrap: break-word" />MODEL<br style="word-wrap: break-word" />RETURN UPDATED ROWS<br style="word-wrap: break-word" />PARTITION BY(ID)<br style="word-wrap: break-word" />DIMENSION BY(row_number() over(PARTITION BY ID ORDER BY col) AS rn)<br style="word-wrap: break-word" />MEASURES (CAST(col AS VARCHAR2(20)) AS str)<br style="word-wrap: break-word" />RULES UPSERT<br style="word-wrap: break-word" />ITERATE(3) UNTIL( presentv(str[iteration_number+2],1,0)=0)<br style="word-wrap: break-word" />(str[0] = str[0] || ',' || str[iteration_number+1])<br style="word-wrap: break-word" />ORDER BY 1;</div>
<div style="word-wrap: break-word">&nbsp;</div>
<div style="word-wrap: break-word">&nbsp;</div></div>
<div style="word-spacing: 0px; font: 16px/26px 宋体, Arial; text-transform: none; color: rgb(102,102,102); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; word-wrap: break-word; orphans: auto; widows: auto; webkit-text-stroke-width: 0px">下面是原文：</div>
<div style="word-spacing: 0px; font: 16px/26px 宋体, Arial; text-transform: none; color: rgb(102,102,102); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; word-wrap: break-word; orphans: auto; widows: auto; webkit-text-stroke-width: 0px">1.<br style="word-wrap: break-word" />概述<br style="word-wrap: break-word" />最近论坛很多人提的问题都与行列转换有关系，所以我对行列转换的相关知识做了一个总结，希望对大家有所帮助，同时有何错疏，恳请大家指出，我也是在写作过程中学习，算是一起和大家学习吧！<br style="word-wrap: break-word" />行列转换包括以下六种情况：<br style="word-wrap: break-word" />1)<br style="word-wrap: break-word" />列转行<br style="word-wrap: break-word" />2)<br style="word-wrap: break-word" />行转列<br style="word-wrap: break-word" />3)<br style="word-wrap: break-word" />多列转换成字符串<br style="word-wrap: break-word" />4)<br style="word-wrap: break-word" />多行转换成字符串<br style="word-wrap: break-word" />5)<br style="word-wrap: break-word" />字符串转换成多列<br style="word-wrap: break-word" />6)<br style="word-wrap: break-word" />字符串转换成多行<br style="word-wrap: break-word" />下面分别进行举例介绍。<br style="word-wrap: break-word" />首先声明一点，有些例子需要如下10g及以后才有的知识：<br style="word-wrap: break-word" />A.<br style="word-wrap: break-word" />掌握model子句<br style="word-wrap: break-word" />B.<br style="word-wrap: break-word" />正则表达式<br style="word-wrap: break-word" />C.<br style="word-wrap: break-word" />加强的层次查询<br style="word-wrap: break-word" />讨论的适用范围只包括8i,9i,10g及以后版本。<br style="word-wrap: break-word" />2.<br style="word-wrap: break-word" />列转行<br style="word-wrap: break-word" />CREATE TABLE t_col_row(<br style="word-wrap: break-word" />ID INT,<br style="word-wrap: break-word" />c1 VARCHAR2(10),<br style="word-wrap: break-word" />c2 VARCHAR2(10),<br style="word-wrap: break-word" />c3 VARCHAR2(10));<br style="word-wrap: break-word" />INSERT INTO t_col_row VALUES (1, 'v11', 'v21', 'v31');<br style="word-wrap: break-word" />INSERT INTO t_col_row VALUES (2, 'v12', 'v22', NULL);<br style="word-wrap: break-word" />INSERT INTO t_col_row VALUES (3, 'v13', NULL, 'v33');<br style="word-wrap: break-word" />INSERT INTO t_col_row VALUES (4, NULL, 'v24', 'v34');<br style="word-wrap: break-word" />INSERT INTO t_col_row VALUES (5, 'v15', NULL, NULL);<br style="word-wrap: break-word" />INSERT INTO t_col_row VALUES (6, NULL, NULL, 'v35');<br style="word-wrap: break-word" />INSERT INTO t_col_row VALUES (7, NULL, NULL, NULL);<br style="word-wrap: break-word" />COMMIT;<br style="word-wrap: break-word" />SELECT * FROM t_col_row;<br style="word-wrap: break-word" />2.1<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT id, 'c1' cn, c1 cv<br style="word-wrap: break-word" />FROM t_col_row<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />SELECT id, 'c2' cn, c2 cv<br style="word-wrap: break-word" />FROM t_col_row<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />SELECT id, 'c3' cn, c3 cv FROM t_col_row;<br style="word-wrap: break-word" />若空行不需要转换，只需加一个where条件，<br style="word-wrap: break-word" />WHERE COLUMN IS NOT NULL 即可。<br style="word-wrap: break-word" />2.2<br style="word-wrap: break-word" />MODEL<br style="word-wrap: break-word" />适用范围：10g及以后<br style="word-wrap: break-word" />SELECT id, cn, cv FROM t_col_row<br style="word-wrap: break-word" />MODEL<br style="word-wrap: break-word" />RETURN UPDATED ROWS<br style="word-wrap: break-word" />PARTITION BY (ID)<br style="word-wrap: break-word" />DIMENSION BY (0 AS n)<br style="word-wrap: break-word" />MEASURES ('xx' AS cn,'yyy' AS cv,c1,c2,c3)<br style="word-wrap: break-word" />RULES UPSERT ALL<br style="word-wrap: break-word" />(<br style="word-wrap: break-word" />cn[1] = 'c1',<br style="word-wrap: break-word" />cn[2] = 'c2',<br style="word-wrap: break-word" />cn[3] = 'c3',<br style="word-wrap: break-word" />cv[1] = c1[0],<br style="word-wrap: break-word" />cv[2] = c2[0],<br style="word-wrap: break-word" />cv[3] = c3[0]<br style="word-wrap: break-word" />)<br style="word-wrap: break-word" />ORDER BY ID,cn;<br style="word-wrap: break-word" />2.3<br style="word-wrap: break-word" />COLLECTION<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />要创建一个对象和一个集合：<br style="word-wrap: break-word" />CREATE TYPE cv_pair AS OBJECT(cn VARCHAR2(10),cv VARCHAR2(10));<br style="word-wrap: break-word" />CREATE TYPE cv_varr AS VARRAY(8) OF cv_pair;<br style="word-wrap: break-word" />SELECT id, t.cn AS cn, t.cv AS cv<br style="word-wrap: break-word" />FROM t_col_row,<br style="word-wrap: break-word" />TABLE(cv_varr(cv_pair('c1', t_col_row.c1),<br style="word-wrap: break-word" />cv_pair('c2', t_col_row.c2),<br style="word-wrap: break-word" />cv_pair('c3', t_col_row.c3))) t<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />3.<br style="word-wrap: break-word" />行转列<br style="word-wrap: break-word" />CREATE TABLE t_row_col AS<br style="word-wrap: break-word" />SELECT id, 'c1' cn, c1 cv<br style="word-wrap: break-word" />FROM t_col_row<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />SELECT id, 'c2' cn, c2 cv<br style="word-wrap: break-word" />FROM t_col_row<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />SELECT id, 'c3' cn, c3 cv FROM t_col_row;<br style="word-wrap: break-word" />SELECT * FROM t_row_col ORDER BY 1,2;<br style="word-wrap: break-word" />3.1<br style="word-wrap: break-word" />AGGREGATE FUNCTION<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />MAX(decode(cn, 'c1', cv, NULL)) AS c1,<br style="word-wrap: break-word" />MAX(decode(cn, 'c2', cv, NULL)) AS c2,<br style="word-wrap: break-word" />MAX(decode(cn, 'c3', cv, NULL)) AS c3<br style="word-wrap: break-word" />FROM t_row_col<br style="word-wrap: break-word" />GROUP BY id<br style="word-wrap: break-word" />ORDER BY 1;<br style="word-wrap: break-word" />MAX聚集函数也可以用sum、min、avg等其他聚集函数替代。<br style="word-wrap: break-word" />被指定的转置列只能有一列，但固定的列可以有多列，请看下面的例子：<br style="word-wrap: break-word" />SELECT mgr, deptno, empno, ename FROM emp ORDER BY 1, 2;<br style="word-wrap: break-word" />SELECT mgr,<br style="word-wrap: break-word" />deptno,<br style="word-wrap: break-word" />MAX(decode(empno, '7788', ename, NULL)) "7788",<br style="word-wrap: break-word" />MAX(decode(empno, '7902', ename, NULL)) "7902",<br style="word-wrap: break-word" />MAX(decode(empno, '7844', ename, NULL)) "7844",<br style="word-wrap: break-word" />MAX(decode(empno, '7521', ename, NULL)) "7521",<br style="word-wrap: break-word" />MAX(decode(empno, '7900', ename, NULL)) "7900",<br style="word-wrap: break-word" />MAX(decode(empno, '7499', ename, NULL)) "7499",<br style="word-wrap: break-word" />MAX(decode(empno, '7654', ename, NULL)) "7654"<br style="word-wrap: break-word" />FROM emp<br style="word-wrap: break-word" />WHERE mgr IN (7566, 7698)<br style="word-wrap: break-word" />AND deptno IN (20, 30)<br style="word-wrap: break-word" />GROUP BY mgr, deptno<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />这里转置列为empno，固定列为mgr，deptno。<br style="word-wrap: break-word" />还有一种行转列的方式，就是相同组中的行值变为单个列值，但转置的行值不变为列名：<br style="word-wrap: break-word" />ID CN_1 CV_1 CN_2 CV_2 CN_3 CV_3<br style="word-wrap: break-word" />1 c1 v11 c2 v21 c3 v31<br style="word-wrap: break-word" />2 c1 v12 c2 v22 c3<br style="word-wrap: break-word" />3 c1 v13 c2 c3 v33<br style="word-wrap: break-word" />4 c1 c2 v24 c3 v34<br style="word-wrap: break-word" />5 c1 v15 c2 c3<br style="word-wrap: break-word" />6 c1 c2 c3 v35<br style="word-wrap: break-word" />7 c1 c2 c3<br style="word-wrap: break-word" />这种情况可以用分析函数实现：<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />MAX(decode(rn, 1, cn, NULL)) cn_1,<br style="word-wrap: break-word" />MAX(decode(rn, 1, cv, NULL)) cv_1,<br style="word-wrap: break-word" />MAX(decode(rn, 2, cn, NULL)) cn_2,<br style="word-wrap: break-word" />MAX(decode(rn, 2, cv, NULL)) cv_2,<br style="word-wrap: break-word" />MAX(decode(rn, 3, cn, NULL)) cn_3,<br style="word-wrap: break-word" />MAX(decode(rn, 3, cv, NULL)) cv_3<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />cn,<br style="word-wrap: break-word" />cv,<br style="word-wrap: break-word" />row_number() over(PARTITION BY id ORDER BY cn, cv) rn<br style="word-wrap: break-word" />FROM t_row_col)<br style="word-wrap: break-word" />GROUP BY ID;<br style="word-wrap: break-word" />3.2<br style="word-wrap: break-word" />PL/SQL<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />这种对于行值不固定的情况可以使用。<br style="word-wrap: break-word" />下面是我写的一个包，包中<br style="word-wrap: break-word" />p_rows_column_real用于前述的第一种不限定列的转换；<br style="word-wrap: break-word" />p_rows_column用于前述的第二种不限定列的转换。<br style="word-wrap: break-word" />CREATE OR REPLACE PACKAGE pkg_dynamic_rows_column AS<br style="word-wrap: break-word" />TYPE refc IS REF CURSOR;<br style="word-wrap: break-word" />PROCEDURE p_print_sql(p_txt VARCHAR2);<br style="word-wrap: break-word" />FUNCTION f_split_str(p_str VARCHAR2, p_division VARCHAR2, p_seq INT)<br style="word-wrap: break-word" />RETURN VARCHAR2;<br style="word-wrap: break-word" />PROCEDURE p_rows_column(p_table IN VARCHAR2,<br style="word-wrap: break-word" />p_keep_cols IN VARCHAR2,<br style="word-wrap: break-word" />p_pivot_cols IN VARCHAR2,<br style="word-wrap: break-word" />p_where IN VARCHAR2 DEFAULT NULL,<br style="word-wrap: break-word" />p_refc IN OUT refc);<br style="word-wrap: break-word" />PROCEDURE p_rows_column_real(p_table IN VARCHAR2,<br style="word-wrap: break-word" />p_keep_cols IN VARCHAR2,<br style="word-wrap: break-word" />p_pivot_col IN VARCHAR2,<br style="word-wrap: break-word" />p_pivot_val IN VARCHAR2,<br style="word-wrap: break-word" />p_where IN VARCHAR2 DEFAULT NULL,<br style="word-wrap: break-word" />p_refc IN OUT refc);<br style="word-wrap: break-word" />END;<br style="word-wrap: break-word" />/<br style="word-wrap: break-word" />CREATE OR REPLACE PACKAGE BODY pkg_dynamic_rows_column AS<br style="word-wrap: break-word" />PROCEDURE p_print_sql(p_txt VARCHAR2) IS<br style="word-wrap: break-word" />v_len INT;<br style="word-wrap: break-word" />BEGIN<br style="word-wrap: break-word" />v_len := length(p_txt);<br style="word-wrap: break-word" />FOR i IN 1 .. v_len / 250 + 1 LOOP<br style="word-wrap: break-word" />dbms_output.put_line(substrb(p_txt, (i - 1) * 250 + 1, 250));<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />END;<br style="word-wrap: break-word" />FUNCTION f_split_str(p_str VARCHAR2, p_division VARCHAR2, p_seq INT)<br style="word-wrap: break-word" />RETURN VARCHAR2 IS<br style="word-wrap: break-word" />v_first INT;<br style="word-wrap: break-word" />v_last INT;<br style="word-wrap: break-word" />BEGIN<br style="word-wrap: break-word" />IF p_seq &lt; 1 THEN<br style="word-wrap: break-word" />RETURN NULL;<br style="word-wrap: break-word" />END IF;<br style="word-wrap: break-word" />IF p_seq = 1 THEN<br style="word-wrap: break-word" />IF instr(p_str, p_division, 1, p_seq) = 0 THEN<br style="word-wrap: break-word" />RETURN p_str;<br style="word-wrap: break-word" />ELSE<br style="word-wrap: break-word" />RETURN substr(p_str, 1, instr(p_str, p_division, 1) - 1);<br style="word-wrap: break-word" />END IF;<br style="word-wrap: break-word" />ELSE<br style="word-wrap: break-word" />v_first := instr(p_str, p_division, 1, p_seq - 1);<br style="word-wrap: break-word" />v_last := instr(p_str, p_division, 1, p_seq);<br style="word-wrap: break-word" />IF (v_last = 0) THEN<br style="word-wrap: break-word" />IF (v_first &gt; 0) THEN<br style="word-wrap: break-word" />RETURN substr(p_str, v_first + 1);<br style="word-wrap: break-word" />ELSE<br style="word-wrap: break-word" />RETURN NULL;<br style="word-wrap: break-word" />END IF;<br style="word-wrap: break-word" />ELSE<br style="word-wrap: break-word" />RETURN substr(p_str, v_first + 1, v_last - v_first - 1);<br style="word-wrap: break-word" />END IF;<br style="word-wrap: break-word" />END IF;<br style="word-wrap: break-word" />END f_split_str;<br style="word-wrap: break-word" />PROCEDURE p_rows_column(p_table IN VARCHAR2,<br style="word-wrap: break-word" />p_keep_cols IN VARCHAR2,<br style="word-wrap: break-word" />p_pivot_cols IN VARCHAR2,<br style="word-wrap: break-word" />p_where IN VARCHAR2 DEFAULT NULL,<br style="word-wrap: break-word" />p_refc IN OUT refc) IS<br style="word-wrap: break-word" />v_sql VARCHAR2(4000);<br style="word-wrap: break-word" />TYPE v_keep_ind_by IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;<br style="word-wrap: break-word" />v_keep v_keep_ind_by;<br style="word-wrap: break-word" />TYPE v_pivot_ind_by IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;<br style="word-wrap: break-word" />v_pivot v_pivot_ind_by;<br style="word-wrap: break-word" />v_keep_cnt INT;<br style="word-wrap: break-word" />v_pivot_cnt INT;<br style="word-wrap: break-word" />v_max_cols INT;<br style="word-wrap: break-word" />v_partition VARCHAR2(4000);<br style="word-wrap: break-word" />v_partition1 VARCHAR2(4000);<br style="word-wrap: break-word" />v_partition2 VARCHAR2(4000);<br style="word-wrap: break-word" />BEGIN<br style="word-wrap: break-word" />v_keep_cnt := length(p_keep_cols) - length(REPLACE(p_keep_cols, ',')) + 1;<br style="word-wrap: break-word" />v_pivot_cnt := length(p_pivot_cols) -<br style="word-wrap: break-word" />length(REPLACE(p_pivot_cols, ',')) + 1;<br style="word-wrap: break-word" />FOR i IN 1 .. v_keep_cnt LOOP<br style="word-wrap: break-word" />v_keep(i) := f_split_str(p_keep_cols, ',', i);<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />FOR j IN 1 .. v_pivot_cnt LOOP<br style="word-wrap: break-word" />v_pivot(j) := f_split_str(p_pivot_cols, ',', j);<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />v_sql := 'select max(count(*)) from ' || p_table || ' group by ';<br style="word-wrap: break-word" />FOR i IN 1 .. v_keep.LAST LOOP<br style="word-wrap: break-word" />v_sql := v_sql || v_keep(i) || ',';<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />v_sql := rtrim(v_sql, ',');<br style="word-wrap: break-word" />EXECUTE IMMEDIATE v_sql<br style="word-wrap: break-word" />INTO v_max_cols;<br style="word-wrap: break-word" />v_partition := 'select ';<br style="word-wrap: break-word" />FOR x IN 1 .. v_keep.COUNT LOOP<br style="word-wrap: break-word" />v_partition1 := v_partition1 || v_keep(x) || ',';<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />FOR y IN 1 .. v_pivot.COUNT LOOP<br style="word-wrap: break-word" />v_partition2 := v_partition2 || v_pivot(y) || ',';<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />v_partition1 := rtrim(v_partition1, ',');<br style="word-wrap: break-word" />v_partition2 := rtrim(v_partition2, ',');<br style="word-wrap: break-word" />v_partition := v_partition || v_partition1 || ',' || v_partition2 ||<br style="word-wrap: break-word" />', row_number() over (partition by ' || v_partition1 ||<br style="word-wrap: break-word" />' order by ' || v_partition2 || ') rn from ' || p_table;<br style="word-wrap: break-word" />v_partition := rtrim(v_partition, ',');<br style="word-wrap: break-word" />v_sql := 'select ';<br style="word-wrap: break-word" />FOR i IN 1 .. v_keep.COUNT LOOP<br style="word-wrap: break-word" />v_sql := v_sql || v_keep(i) || ',';<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />FOR i IN 1 .. v_max_cols LOOP<br style="word-wrap: break-word" />FOR j IN 1 .. v_pivot.COUNT LOOP<br style="word-wrap: break-word" />v_sql := v_sql || ' max(decode(rn,' || i || ',' || v_pivot(j) ||<br style="word-wrap: break-word" />',null))' || v_pivot(j) || '_' || i || ',';<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />IF p_where IS NOT NULL THEN<br style="word-wrap: break-word" />v_sql := rtrim(v_sql, ',') || ' from (' || v_partition || ' ' ||<br style="word-wrap: break-word" />p_where || ') group by ';<br style="word-wrap: break-word" />ELSE<br style="word-wrap: break-word" />v_sql := rtrim(v_sql, ',') || ' from (' || v_partition ||<br style="word-wrap: break-word" />') group by ';<br style="word-wrap: break-word" />END IF;<br style="word-wrap: break-word" />FOR i IN 1 .. v_keep.COUNT LOOP<br style="word-wrap: break-word" />v_sql := v_sql || v_keep(i) || ',';<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />v_sql := rtrim(v_sql, ',');<br style="word-wrap: break-word" />p_print_sql(v_sql);<br style="word-wrap: break-word" />OPEN p_refc FOR v_sql;<br style="word-wrap: break-word" />EXCEPTION<br style="word-wrap: break-word" />WHEN OTHERS THEN<br style="word-wrap: break-word" />OPEN p_refc FOR<br style="word-wrap: break-word" />SELECT 'x' FROM dual WHERE 0 = 1;<br style="word-wrap: break-word" />END;<br style="word-wrap: break-word" />PROCEDURE p_rows_column_real(p_table IN VARCHAR2,<br style="word-wrap: break-word" />p_keep_cols IN VARCHAR2,<br style="word-wrap: break-word" />p_pivot_col IN VARCHAR2,<br style="word-wrap: break-word" />p_pivot_val IN VARCHAR2,<br style="word-wrap: break-word" />p_where IN VARCHAR2 DEFAULT NULL,<br style="word-wrap: break-word" />p_refc IN OUT refc) IS<br style="word-wrap: break-word" />v_sql VARCHAR2(4000);<br style="word-wrap: break-word" />TYPE v_keep_ind_by IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;<br style="word-wrap: break-word" />v_keep v_keep_ind_by;<br style="word-wrap: break-word" />TYPE v_pivot_ind_by IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;<br style="word-wrap: break-word" />v_pivot v_pivot_ind_by;<br style="word-wrap: break-word" />v_keep_cnt INT;<br style="word-wrap: break-word" />v_group_by VARCHAR2(2000);<br style="word-wrap: break-word" />BEGIN<br style="word-wrap: break-word" />v_keep_cnt := length(p_keep_cols) - length(REPLACE(p_keep_cols, ',')) + 1;<br style="word-wrap: break-word" />FOR i IN 1 .. v_keep_cnt LOOP<br style="word-wrap: break-word" />v_keep(i) := f_split_str(p_keep_cols, ',', i);<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />v_sql := 'select ' || 'cast(' || p_pivot_col ||<br style="word-wrap: break-word" />' as varchar2(200)) as ' || p_pivot_col || ' from ' || p_table ||<br style="word-wrap: break-word" />' group by ' || p_pivot_col;<br style="word-wrap: break-word" />EXECUTE IMMEDIATE v_sql BULK COLLECT<br style="word-wrap: break-word" />INTO v_pivot;<br style="word-wrap: break-word" />FOR i IN 1 .. v_keep.COUNT LOOP<br style="word-wrap: break-word" />v_group_by := v_group_by || v_keep(i) || ',';<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />v_group_by := rtrim(v_group_by, ',');<br style="word-wrap: break-word" />v_sql := 'select ' || v_group_by || ',';<br style="word-wrap: break-word" />FOR x IN 1 .. v_pivot.COUNT LOOP<br style="word-wrap: break-word" />v_sql := v_sql || ' max(decode(' || p_pivot_col || ',' || chr(39) ||<br style="word-wrap: break-word" />v_pivot(x) || chr(39) || ',' || p_pivot_val ||<br style="word-wrap: break-word" />',null)) as "' || v_pivot(x) || '",';<br style="word-wrap: break-word" />END LOOP;<br style="word-wrap: break-word" />v_sql := rtrim(v_sql, ',');<br style="word-wrap: break-word" />IF p_where IS NOT NULL THEN<br style="word-wrap: break-word" />v_sql := v_sql || ' from ' || p_table || p_where || ' group by ' ||<br style="word-wrap: break-word" />v_group_by;<br style="word-wrap: break-word" />ELSE<br style="word-wrap: break-word" />v_sql := v_sql || ' from ' || p_table || ' group by ' || v_group_by;<br style="word-wrap: break-word" />END IF;<br style="word-wrap: break-word" />p_print_sql(v_sql);<br style="word-wrap: break-word" />OPEN p_refc FOR v_sql;<br style="word-wrap: break-word" />EXCEPTION<br style="word-wrap: break-word" />WHEN OTHERS THEN<br style="word-wrap: break-word" />OPEN p_refc FOR<br style="word-wrap: break-word" />SELECT 'x' FROM dual WHERE 0 = 1;<br style="word-wrap: break-word" />END;<br style="word-wrap: break-word" />END;<br style="word-wrap: break-word" />/<br style="word-wrap: break-word" />4.<br style="word-wrap: break-word" />多列转换成字符串<br style="word-wrap: break-word" />CREATE TABLE t_col_str AS<br style="word-wrap: break-word" />SELECT * FROM t_col_row;<br style="word-wrap: break-word" />这个比较简单，用||或concat函数可以实现：<br style="word-wrap: break-word" />SELECT concat('a','b') FROM dual;<br style="word-wrap: break-word" />4.1<br style="word-wrap: break-word" />|| OR CONCAT<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT * FROM t_col_str;<br style="word-wrap: break-word" />SELECT ID,c1||','||c2||','||c3 AS c123<br style="word-wrap: break-word" />FROM t_col_str;<br style="word-wrap: break-word" />5.<br style="word-wrap: break-word" />多行转换成字符串<br style="word-wrap: break-word" />CREATE TABLE t_row_str(<br style="word-wrap: break-word" />ID INT,<br style="word-wrap: break-word" />col VARCHAR2(10));<br style="word-wrap: break-word" />INSERT INTO t_row_str VALUES(1,'a');<br style="word-wrap: break-word" />INSERT INTO t_row_str VALUES(1,'b');<br style="word-wrap: break-word" />INSERT INTO t_row_str VALUES(1,'c');<br style="word-wrap: break-word" />INSERT INTO t_row_str VALUES(2,'a');<br style="word-wrap: break-word" />INSERT INTO t_row_str VALUES(2,'d');<br style="word-wrap: break-word" />INSERT INTO t_row_str VALUES(2,'e');<br style="word-wrap: break-word" />INSERT INTO t_row_str VALUES(3,'c');<br style="word-wrap: break-word" />COMMIT;<br style="word-wrap: break-word" />SELECT * FROM t_row_str;<br style="word-wrap: break-word" />5.1<br style="word-wrap: break-word" />MAX + DECODE<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />MAX(decode(rn, 1, col, NULL)) ||<br style="word-wrap: break-word" />MAX(decode(rn, 2, ',' || col, NULL)) ||<br style="word-wrap: break-word" />MAX(decode(rn, 3, ',' || col, NULL)) str<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />col,<br style="word-wrap: break-word" />row_number() over(PARTITION BY id ORDER BY col) AS rn<br style="word-wrap: break-word" />FROM t_row_str) t<br style="word-wrap: break-word" />GROUP BY id<br style="word-wrap: break-word" />ORDER BY 1;<br style="word-wrap: break-word" />5.2<br style="word-wrap: break-word" />ROW_NUMBER + LEAD<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT id, str<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />row_number() over(PARTITION BY id ORDER BY col) AS rn,<br style="word-wrap: break-word" />col || lead(',' || col, 1) over(PARTITION BY id ORDER BY col) ||<br style="word-wrap: break-word" />lead(',' || col, 2) over(PARTITION BY id ORDER BY col) ||<br style="word-wrap: break-word" />lead(',' || col, 3) over(PARTITION BY id ORDER BY col) AS str<br style="word-wrap: break-word" />FROM t_row_str)<br style="word-wrap: break-word" />WHERE rn = 1<br style="word-wrap: break-word" />ORDER BY 1;<br style="word-wrap: break-word" />5.3<br style="word-wrap: break-word" />MODEL<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />SELECT id, substr(str, 2) str FROM t_row_str<br style="word-wrap: break-word" />MODEL<br style="word-wrap: break-word" />RETURN UPDATED ROWS<br style="word-wrap: break-word" />PARTITION BY(ID)<br style="word-wrap: break-word" />DIMENSION BY(row_number() over(PARTITION BY ID ORDER BY col) AS rn)<br style="word-wrap: break-word" />MEASURES (CAST(col AS VARCHAR2(20)) AS str)<br style="word-wrap: break-word" />RULES UPSERT<br style="word-wrap: break-word" />ITERATE(3) UNTIL( presentv(str[iteration_number+2],1,0)=0)<br style="word-wrap: break-word" />(str[0] = str[0] || ',' || str[iteration_number+1])<br style="word-wrap: break-word" />ORDER BY 1;<br style="word-wrap: break-word" />5.4<br style="word-wrap: break-word" />SYS_CONNECT_BY_PATH<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT t.id id, MAX(substr(sys_connect_by_path(t.col, ','), 2)) str<br style="word-wrap: break-word" />FROM (SELECT id, col, row_number() over(PARTITION BY id ORDER BY col) rn<br style="word-wrap: break-word" />FROM t_row_str) t<br style="word-wrap: break-word" />START WITH rn = 1<br style="word-wrap: break-word" />CONNECT BY rn = PRIOR rn + 1<br style="word-wrap: break-word" />AND id = PRIOR id<br style="word-wrap: break-word" />GROUP BY t.id;<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />SELECT t.id id, substr(sys_connect_by_path(t.col, ','), 2) str<br style="word-wrap: break-word" />FROM (SELECT id, col, row_number() over(PARTITION BY id ORDER BY col) rn<br style="word-wrap: break-word" />FROM t_row_str) t<br style="word-wrap: break-word" />WHERE connect_by_isleaf = 1<br style="word-wrap: break-word" />START WITH rn = 1<br style="word-wrap: break-word" />CONNECT BY rn = PRIOR rn + 1<br style="word-wrap: break-word" />AND id = PRIOR id;<br style="word-wrap: break-word" />5.5<br style="word-wrap: break-word" />WMSYS.WM_CONCAT<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />这个函数预定义按','分隔字符串，若要用其他符号分隔可以用，replace将','替换。<br style="word-wrap: break-word" />SELECT id, REPLACE(wmsys.wm_concat(col), ',', '/') str<br style="word-wrap: break-word" />FROM t_row_str<br style="word-wrap: break-word" />GROUP BY id;<br style="word-wrap: break-word" />6.<br style="word-wrap: break-word" />字符串转换成多列<br style="word-wrap: break-word" />其实际上就是一个字符串拆分的问题。<br style="word-wrap: break-word" />CREATE TABLE t_str_col AS<br style="word-wrap: break-word" />SELECT ID,c1||','||c2||','||c3 AS c123<br style="word-wrap: break-word" />FROM t_col_str;<br style="word-wrap: break-word" />SELECT * FROM t_str_col;<br style="word-wrap: break-word" />6.1<br style="word-wrap: break-word" />SUBSTR + INSTR<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />c123,<br style="word-wrap: break-word" />substr(c123, 1, instr(c123 || ',', ',', 1, 1) - 1) c1,<br style="word-wrap: break-word" />substr(c123,<br style="word-wrap: break-word" />instr(c123 || ',', ',', 1, 1) + 1,<br style="word-wrap: break-word" />instr(c123 || ',', ',', 1, 2) - instr(c123 || ',', ',', 1, 1) - 1) c2,<br style="word-wrap: break-word" />substr(c123,<br style="word-wrap: break-word" />instr(c123 || ',', ',', 1, 2) + 1,<br style="word-wrap: break-word" />instr(c123 || ',', ',', 1, 3) - instr(c123 || ',', ',', 1, 2) - 1) c3<br style="word-wrap: break-word" />FROM t_str_col<br style="word-wrap: break-word" />ORDER BY 1;<br style="word-wrap: break-word" />6.2<br style="word-wrap: break-word" />REGEXP_SUBSTR<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />c123,<br style="word-wrap: break-word" />rtrim(regexp_substr(c123 || ',', '.*?' || ',', 1, 1), ',') AS c1,<br style="word-wrap: break-word" />rtrim(regexp_substr(c123 || ',', '.*?' || ',', 1, 2), ',') AS c2,<br style="word-wrap: break-word" />rtrim(regexp_substr(c123 || ',', '.*?' || ',', 1, 3), ',') AS c3<br style="word-wrap: break-word" />FROM t_str_col<br style="word-wrap: break-word" />ORDER BY 1;<br style="word-wrap: break-word" />7.<br style="word-wrap: break-word" />字符串转换成多行<br style="word-wrap: break-word" />CREATE TABLE t_str_row AS<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />MAX(decode(rn, 1, col, NULL)) ||<br style="word-wrap: break-word" />MAX(decode(rn, 2, ',' || col, NULL)) ||<br style="word-wrap: break-word" />MAX(decode(rn, 3, ',' || col, NULL)) str<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />col,<br style="word-wrap: break-word" />row_number() over(PARTITION BY id ORDER BY col) AS rn<br style="word-wrap: break-word" />FROM t_row_str) t<br style="word-wrap: break-word" />GROUP BY id<br style="word-wrap: break-word" />ORDER BY 1;<br style="word-wrap: break-word" />SELECT * FROM t_str_row;<br style="word-wrap: break-word" />7.1<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT id, 1 AS p, substr(str, 1, instr(str || ',', ',', 1, 1) - 1) AS cv<br style="word-wrap: break-word" />FROM t_str_row<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />2 AS p,<br style="word-wrap: break-word" />substr(str,<br style="word-wrap: break-word" />instr(str || ',', ',', 1, 1) + 1,<br style="word-wrap: break-word" />instr(str || ',', ',', 1, 2) - instr(str || ',', ',', 1, 1) - 1) AS cv<br style="word-wrap: break-word" />FROM t_str_row<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />3 AS p,<br style="word-wrap: break-word" />substr(str,<br style="word-wrap: break-word" />instr(str || ',', ',', 1, 1) + 1,<br style="word-wrap: break-word" />instr(str || ',', ',', 1, 2) - instr(str || ',', ',', 1, 1) - 1) AS cv<br style="word-wrap: break-word" />FROM t_str_row<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />SELECT id, 1 AS p, rtrim(regexp_substr(str||',', '.*?' || ',', 1, 1), ',') AS cv<br style="word-wrap: break-word" />FROM t_str_row<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />SELECT id, 2 AS p, rtrim(regexp_substr(str||',', '.*?' || ',', 1, 2), ',') AS cv<br style="word-wrap: break-word" />FROM t_str_row<br style="word-wrap: break-word" />UNION ALL<br style="word-wrap: break-word" />SELECT id, 3 AS p, rtrim(regexp_substr(str||',', '.*?' || ',',1,3), ',') AS cv<br style="word-wrap: break-word" />FROM t_str_row<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />7.2<br style="word-wrap: break-word" />VARRAY<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />要创建一个可变数组：<br style="word-wrap: break-word" />CREATE OR REPLACE TYPE ins_seq_type IS VARRAY(8) OF NUMBER;<br style="word-wrap: break-word" />SELECT * FROM TABLE(ins_seq_type(1, 2, 3, 4, 5));<br style="word-wrap: break-word" />SELECT t.id,<br style="word-wrap: break-word" />c.column_value AS p,<br style="word-wrap: break-word" />substr(t.ca,<br style="word-wrap: break-word" />instr(t.ca, ',', 1, c.column_value) + 1,<br style="word-wrap: break-word" />instr(t.ca, ',', 1, c.column_value + 1) -<br style="word-wrap: break-word" />(instr(t.ca, ',', 1, c.column_value) + 1)) AS cv<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />',' || str || ',' AS ca,<br style="word-wrap: break-word" />length(str || ',') - nvl(length(REPLACE(str, ',')), 0) AS cnt<br style="word-wrap: break-word" />FROM t_str_row) t<br style="word-wrap: break-word" />INNER JOIN TABLE(ins_seq_type(1, 2, 3)) c ON c.column_value &lt;=<br style="word-wrap: break-word" />t.cnt<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />7.3<br style="word-wrap: break-word" />SEQUENCE SERIES<br style="word-wrap: break-word" />这类方法主要是要产生一个连续的整数列，产生连续整数列的方法有很多，主要有：<br style="word-wrap: break-word" />CONNECT BY,ROWNUM+all_objects,CUBE等。<br style="word-wrap: break-word" />适用范围：8i,9i,10g及以后版本<br style="word-wrap: break-word" />SELECT t.id,<br style="word-wrap: break-word" />c.lv AS p,<br style="word-wrap: break-word" />substr(t.ca,<br style="word-wrap: break-word" />instr(t.ca, ',', 1, c.lv) + 1,<br style="word-wrap: break-word" />instr(t.ca, ',', 1, c.lv + 1) -<br style="word-wrap: break-word" />(instr(t.ca, ',', 1, c.lv) + 1)) AS cv<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />',' || str || ',' AS ca,<br style="word-wrap: break-word" />length(str || ',') - nvl(length(REPLACE(str, ',')), 0) AS cnt<br style="word-wrap: break-word" />FROM t_str_row) t,<br style="word-wrap: break-word" />(SELECT LEVEL lv FROM dual CONNECT BY LEVEL &lt;= 5) c<br style="word-wrap: break-word" />WHERE c.lv &lt;= t.cnt<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />SELECT t.id,<br style="word-wrap: break-word" />c.rn AS p,<br style="word-wrap: break-word" />substr(t.ca,<br style="word-wrap: break-word" />instr(t.ca, ',', 1, c.rn) + 1,<br style="word-wrap: break-word" />instr(t.ca, ',', 1, c.rn + 1) -<br style="word-wrap: break-word" />(instr(t.ca, ',', 1, c.rn) + 1)) AS cv<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />',' || str || ',' AS ca,<br style="word-wrap: break-word" />length(str || ',') - nvl(length(REPLACE(str, ',')), 0) AS cnt<br style="word-wrap: break-word" />FROM t_str_row) t,<br style="word-wrap: break-word" />(SELECT rownum rn FROM all_objects WHERE rownum &lt;= 5) c<br style="word-wrap: break-word" />WHERE c.rn &lt;= t.cnt<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />SELECT t.id,<br style="word-wrap: break-word" />c.cb AS p,<br style="word-wrap: break-word" />substr(t.ca,<br style="word-wrap: break-word" />instr(t.ca, ',', 1, c.cb) + 1,<br style="word-wrap: break-word" />instr(t.ca, ',', 1, c.cb + 1) -<br style="word-wrap: break-word" />(instr(t.ca, ',', 1, c.cb) + 1)) AS cv<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />',' || str || ',' AS ca,<br style="word-wrap: break-word" />length(str || ',') - nvl(length(REPLACE(str, ',')), 0) AS cnt<br style="word-wrap: break-word" />FROM t_str_row) t,<br style="word-wrap: break-word" />(SELECT rownum cb FROM (SELECT 1 FROM dual GROUP BY CUBE(1, 2))) c<br style="word-wrap: break-word" />WHERE c.cb &lt;= t.cnt<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />SELECT t.id,<br style="word-wrap: break-word" />c.lv AS p,<br style="word-wrap: break-word" />rtrim(regexp_substr(t.str || ',', '.*?' || ',', 1, c.lv), ',') AS cv<br style="word-wrap: break-word" />FROM (SELECT id,<br style="word-wrap: break-word" />str,<br style="word-wrap: break-word" />length(regexp_replace(str || ',', '[^' || ',' || ']', NULL)) AS cnt<br style="word-wrap: break-word" />FROM t_str_row) t<br style="word-wrap: break-word" />INNER JOIN (SELECT LEVEL lv FROM dual CONNECT BY LEVEL &lt;= 5) c ON c.lv &lt;= t.cnt<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />7.4<br style="word-wrap: break-word" />HIERARCHICAL + DBMS_RANDOM<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />LEVEL AS p,<br style="word-wrap: break-word" />rtrim(regexp_substr(str || ',', '.*?' || ',', 1, LEVEL), ',') AS cv<br style="word-wrap: break-word" />FROM t_str_row<br style="word-wrap: break-word" />CONNECT BY id = PRIOR id<br style="word-wrap: break-word" />AND PRIOR dbms_random.VALUE IS NOT NULL<br style="word-wrap: break-word" />AND LEVEL &lt;=<br style="word-wrap: break-word" />length(regexp_replace(str || ',', '[^' || ',' || ']', NULL))<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />7.5<br style="word-wrap: break-word" />HIERARCHICAL + CONNECT_BY_ROOT<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />SELECT id,<br style="word-wrap: break-word" />LEVEL AS p,<br style="word-wrap: break-word" />rtrim(regexp_substr(str || ',', '.*?' || ',', 1, LEVEL), ',') AS cv<br style="word-wrap: break-word" />FROM t_str_row<br style="word-wrap: break-word" />CONNECT BY id = connect_by_root id<br style="word-wrap: break-word" />AND LEVEL &lt;=<br style="word-wrap: break-word" />length(regexp_replace(str || ',', '[^' || ',' || ']', NULL))<br style="word-wrap: break-word" />ORDER BY 1, 2;<br style="word-wrap: break-word" />7.6<br style="word-wrap: break-word" />MODEL<br style="word-wrap: break-word" />适用范围：10g及以后版本<br style="word-wrap: break-word" />SELECT id, p, cv FROM t_str_row<br style="word-wrap: break-word" />MODEL<br style="word-wrap: break-word" />RETURN UPDATED ROWS<br style="word-wrap: break-word" />PARTITION BY(ID)<br style="word-wrap: break-word" />DIMENSION BY( 0 AS p)<br style="word-wrap: break-word" />MEASURES( str||',' AS cv)<br style="word-wrap: break-word" />RULES UPSERT<br style="word-wrap: break-word" />(cv<br style="word-wrap: break-word" />[ FOR p<br style="word-wrap: break-word" />FROM 1 TO length(regexp_replace(cv[0],'[^'||','||']',null))<br /><br />例子：<br /><font face="Verdana">SELECT t.dutyname , substr(sys_connect_by_path(t.username, ','), 2) str<br />FROM (SELECT dutyname, username, row_number() over(PARTITION BY dutyname ORDER BY username) rn<br />FROM test) t<br />WHERE connect_by_isleaf = 1<br />START WITH rn = 1<br />CONNECT BY rn = PRIOR rn + 1<br />AND dutyname = PRIOR dutyname;<br /><!--StartFragment -->

<div><img src="file:///C:/Documents%20and%20Settings/tang/Application%20Data/Tencent/Users/312152218/QQ/WinTemp/RichOle/63TA1[)9QG8P~_93]TX2ANR.png"  alt="" /> </div><br /></font><br /></div><img src ="http://www.blogjava.net/tjyhy590/aggbug/426452.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2015-07-27 23:52 <a href="http://www.blogjava.net/tjyhy590/archive/2015/07/27/426452.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Https通讯原理</title><link>http://www.blogjava.net/tjyhy590/archive/2014/06/13/414715.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Fri, 13 Jun 2014 08:16:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2014/06/13/414715.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/414715.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2014/06/13/414715.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/414715.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/414715.html</trackback:ping><description><![CDATA[ Https是什么?

Https是基于安全目的的Http通道，其安全基础由SSL层来保证。最初由netscape公司研发，主要提供了通讯双方的身份认证和加密通信方法。现在广泛应用于互联网上安全敏感通讯。

Https与Http主要区别

协议基础不同：Https在Http下加入了SSL层，

通讯方式不同：Https在数据通信之前需要客户端、服务器进行握手(身份认证)，建立连接后，传输数据经过加密，通信端口443。

Http传输数据不加密，明文，通信端口80。

SSL协议基础

SSL协议位于TCP/IP协议与各种应用层协议之间，本身又分为两层：

SSL记录协议(SSL Record Protocol)：建立在可靠传输层协议(TCP)之上，为上层协议提供数据封装、压缩、加密等基本功能。

SSL握手协议(SSL Handshake Procotol)：在SSL记录协议之上，用于实际数据传输前，通讯双方进行身份认证、协商加密算法、交换加密密钥等。

SSL协议通信过程

(1) 浏览器发送一个连接请求给服务器;服务器将自己的证书(包含服务器公钥S_PuKey)、对称加密算法种类及其他相关信息返回客户端;

(2) 客户端浏览器检查服务器传送到CA证书是否由自己信赖的CA中心签发。若是，执行4步;否则，给客户一个警告信息：询问是否继续访问。

(3) 客户端浏览器比较证书里的信息，如证书有效期、服务器域名和公钥S_PK，与服务器传回的信息是否一致，如果一致，则浏览器完成对服务器的身份认证。

(4) 服务器要求客户端发送客户端证书(包含客户端公钥C_PuKey)、支持的对称加密方案及其他相关信息。收到后，服务器进行相同的身份认证，若没有通过验证，则拒绝连接;

(5) 服务器根据客户端浏览器发送到密码种类，选择一种加密程度最高的方案，用客户端公钥C_PuKey加密后通知到浏览器;

(6) 客户端通过私钥C_PrKey解密后，得知服务器选择的加密方案，并选择一个通话密钥key，接着用服务器公钥S_PuKey加密后发送给服务器;

(7) 服务器接收到的浏览器传送到消息，用私钥S_PrKey解密，获得通话密钥key。

(8) 接下来的数据传输都使用该对称密钥key进行加密。

上面所述的是双向认证 SSL 协议的具体通讯过程，服务器和用户双方必须都有证书。由此可见，SSL协议是通过非对称密钥机制保证双方身份认证，并完成建立连接，在实际数据通信时通过对称密钥机制保障数据安全性

 <img src ="http://www.blogjava.net/tjyhy590/aggbug/414715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2014-06-13 16:16 <a href="http://www.blogjava.net/tjyhy590/archive/2014/06/13/414715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>js合并指定列值重复的单元格</title><link>http://www.blogjava.net/tjyhy590/archive/2013/07/06/401266.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Sat, 06 Jul 2013 07:09:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2013/07/06/401266.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/401266.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2013/07/06/401266.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/401266.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/401266.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; function uniteTab(tableId,col) { <br />&nbsp;&nbsp;&nbsp;&nbsp; //col-- 需要合并单元格的列 1开始 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var tb=document.getElementById(tableId); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tb.style.display=''; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var i = 0; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var j = 0; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var rowCount = tb.rows.length; //&nbsp;&nbsp; 行数&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var colCount = tb.rows[0].cells.length; //&nbsp;&nbsp; 列数&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var obj1 = null; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var obj2 = null; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //为每个单元格命名&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; rowCount; i++) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (j = 0; j &lt; colCount; j++) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tb.rows[i].cells[j].id = "tb__" + i.toString() + "_" + j.toString(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //合并行&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; colCount; i++) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i == colLength) break; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj1 = document.getElementById("tb__0_" + i.toString()) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (j = 1; j &lt; rowCount; j++) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj2 = document.getElementById("tb__" + j.toString() + "_" + i.toString()); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (obj1.innerText == obj2.innerText) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj1.rowSpan++; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj2.parentNode.removeChild(obj2); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj1 = document.getElementById("tb__" + j.toString() + "_" + i.toString()); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //合并列 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; rowCount; i++) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colCount = tb.rows[i].cells.length; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj1 = document.getElementById(tb.rows[i].cells[0].id); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (j = 1; j &lt; colCount; j++) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (j &gt;= colLength) break; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (obj1.colSpan &gt;= colLength) break; <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj2 = document.getElementById(tb.rows[i].cells[j].id); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (obj1.innerText == obj2.innerText) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj1.colSpan++; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj2.parentNode.removeChild(obj2); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j = j - 1; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj1 = obj2; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j = j + obj1.rowSpan; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; } <br /><img src ="http://www.blogjava.net/tjyhy590/aggbug/401266.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2013-07-06 15:09 <a href="http://www.blogjava.net/tjyhy590/archive/2013/07/06/401266.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库分区表操作方法(4)</title><link>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366192.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Mon, 12 Dec 2011 14:57:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366192.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/366192.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/366192.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/366192.html</trackback:ping><description><![CDATA[<strong>1.3. 分区表索引的使用：</strong> <br /><br />　　 分区表和一般表一样可以建立索引，分区表可以创建局部索引和全局索引。当分区中出现许多事务并且要保证所有分区中的数据记录的唯一性时采用全局索引。 <br /><br />　　 1.3.1. 局部索引分区的建立： <br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; create index dinya_idx_t on dinya_test(item_id) <br />2 local <br />3 ( <br />4 partition idx_1 tablespace dinya_space01, <br />5 partition idx_2 tablespace dinya_space02, <br />6 partition idx_3 tablespace dinya_space03 <br />7 ); <br />Index created. <br />SQL&gt;</font></td></tr></tbody></table><br />　　 看查询的执行计划，从下面的执行计划可以看出，系统已经使用了索引： <br /><br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; select * from dinya_test partition(part_01) t where t.item_id=12; <br />Execution Plan <br />---------------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=187) <br />1 0 TABLE ACCESS (BY LOCAL INDEX ROWID) OF &#8217;DINYA_TEST&#8217; (Cost= <br />2 Card=1 Bytes=187) <br />2 1 INDEX (RANGE SCAN) OF &#8217;DINYA_IDX_T&#8217; (NON-UNIQUE) (Cost=1 <br />Card=1) <br />Statistics <br />---------------------------------------------------------- <br />0 recursive calls <br />0 db block gets <br />4 consistent gets <br />0 physical reads <br />0 redo size <br />334 bytes sent via SQL*Net to client <br />309 bytes received via SQL*Net from client <br />2 SQL*Net roundtrips to/from client <br /><br />1 sorts (memory) <br />0 sorts (disk) <br />2 rows processed <br />SQL&gt;</font></td></tr></tbody></table><br />　　 1.3.2. 全局索引分区的建立<br /><br />　　 全局索引建立时global 子句允许指定索引的范围值，这个范围值为索引字段的范围值： <br /><br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; create index dinya_idx_t on dinya_test(item_id) <br />2 global partition by range(item_id) <br />3 ( <br />4 partition idx_1 values less than (1000) tablespace dinya_space01, <br />5 partition idx_2 values less than (10000) tablespace dinya_space02, <br />6 partition idx_3 values less than (maxvalue) tablespace dinya_space03 <br />7 ); <br />Index created. <br />SQL&gt;</font></td></tr></tbody></table><br />　　 本例中对表的item_id字段建立索引分区，当然也可以不指定索引分区名直接对整个表建立索引，如： <br /><br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; create index dinya_idx_t on dinya_test(item_id); <br />Index created. <br />SQL&gt;</font></td></tr></tbody></table><br />　　 同样的，对全局索引根据执行计划可以看出索引已经可以使用： <br /><br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; select * from dinya_test t where t.item_id=12; <br />Execution Plan <br />---------------------------------------------------------- <br />0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=3 Bytes=561) <br />1 0 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF &#8217;DINYA_TEST&#8217; (Cost <br />=2 Card=3 Bytes=561) <br />2 1 INDEX (RANGE SCAN) OF &#8217;DINYA_IDX_T&#8217; (NON-UNIQUE) (Cost=1 <br />Card=3) <br />Statistics <br />---------------------------------------------------------- <br />5 recursive calls <br />0 db block gets <br />10 consistent gets <br />0 physical reads <br /><br />0 redo size <br />420 bytes sent via SQL*Net to client <br />309 bytes received via SQL*Net from client <br />2 SQL*Net roundtrips to/from client <br />3 sorts (memory) <br />0 sorts (disk) <br />5 rows processed <br />SQL&gt;</font></td></tr></tbody></table><img src ="http://www.blogjava.net/tjyhy590/aggbug/366192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-12-12 22:57 <a href="http://www.blogjava.net/tjyhy590/archive/2011/12/12/366192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库分区表操作方法(5)</title><link>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366193.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Mon, 12 Dec 2011 14:57:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366193.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/366193.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/366193.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/366193.html</trackback:ping><description><![CDATA[<p><strong>1.4. 分区表的维护： <br /><br /></strong>　　 了解了分区表的建立、索引的建立、表和索引的使用后，在应用的还要经常对分区进行维护和管理。日常维护和管理的内容包括：增加一个分区，合并一个分区及删除分区等等。下面以范围分区为例说明增加、合并、删除分区的一般操作： <br /><br />　　 1.4.1. 增加一个分区: <br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; alter table dinya_test <br />2 add partition part_04 values less than(to_date(&#8217;2012-01-01&#8217;,&#8217;yyyy-mm-dd&#8217;)) <br />tablespace dinya_spa <br />ce03; <br />Table altered. <br />SQL&gt;</font></td></tr></tbody></table><br />　　 增加一个分区的时候，增加的分区的条件必须大于现有分区的最大值，否则系统将提示ORA-14074 partition bound must collate higher than that of the last partition 错误。 <br /><br />　　 1.4.2. 合并一个分区： <br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; alter table dinya_test merge partitions part_01,part_02 into partition part_02; <br />Table altered. <br />SQL&gt;</font></td></tr></tbody></table><br />　　 在本例中将原有的表的part_01分区和part_02分区进行了合并，合并后的分区为part_02,如果在合并的时候把合并后的分区定为part_01的时候，系统将提示ORA-14275 cannot reuse lower-bound partition as resulting partition 错误。 <br /><br />　　 1.4.3. 删除分区： <br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; alter table dinya_test drop partition part_01; <br />Table altered. <br />SQL&gt;</font></td></tr></tbody></table><br />　　 删除分区表的一个分区后，查询该表的数据时显示，该分区中的数据已全部丢失，所以执行删除分区动作时要慎重，确保先备份数据后再执行，或将分区合并。 <br /><br />　　<strong>1.5. 总结：</strong> <br /><br />　　 需要说明的是，本文在举例说名分区表事务操作的时候，都指定了分区，因为指定了分区，系统在执行的时候则只操作该分区的记录，提高了数据处理的速度。不要指定分区直接操作数据也是可以的。在分区表上建索引及多索引的使用和非分区表一样。此外，因为在维护分区的时候可能对分区的索引会产生一定的影响，可能需要在维护之后重建索引，相关内容请参考分区表索引部分的文档 </p><img src ="http://www.blogjava.net/tjyhy590/aggbug/366193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-12-12 22:57 <a href="http://www.blogjava.net/tjyhy590/archive/2011/12/12/366193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库分区表操作方法(3)</title><link>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366191.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Mon, 12 Dec 2011 14:56:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366191.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/366191.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366191.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/366191.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/366191.html</trackback:ping><description><![CDATA[<p><strong>1.2. 分区表操作</strong> <br /><br />　　 以上了解了三种分区表的建表方法，下面将使用实际的数据并针对按日期的范围分区来测试分区表的数据记录的操作。 <br /><br />　　 1.2.1. 插入记录： 
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; insert into dinya_test values(1,12,&#8217;BOOKS&#8217;,sysdate); <br />1 row created. <br />SQL&gt; insert into dinya_test values(2,12, &#8217;BOOKS&#8217;,sysdate+30); <br />1 row created. <br /><br />SQL&gt; insert into dinya_test values(3,12, &#8217;BOOKS&#8217;,to_date(&#8217;2006-05-30&#8217;,&#8217;yyyy-mm-dd&#8217;)); <br />1 row created. <br />SQL&gt; insert into dinya_test values(4,12, &#8217;BOOKS&#8217;,to_date(&#8217;2007-06-23&#8217;,&#8217;yyyy-mm-dd&#8217;)); <br />1 row created. <br />SQL&gt; insert into dinya_test values(5,12, &#8217;BOOKS&#8217;,to_date(&#8217;2011-02-26&#8217;,&#8217;yyyy-mm-dd&#8217;)); <br />1 row created. <br />SQL&gt; insert into dinya_test values(6,12, &#8217;BOOKS&#8217;,to_date(&#8217;2011-04-30&#8217;,&#8217;yyyy-mm-dd&#8217;)); <br />1 row created. <br />SQL&gt; commit; <br />Commit complete. <br />SQL&gt; </font></td></tr></tbody></table>　　 按上面的建表结果，2006年前的数据将存储在第一个分区part_01上，而2006年到2010年的交易数据将存储在第二个分区part_02上，2010年以后的记录存储在第三个分区part_03上。 <br /><br /><br />　　 1.2.2. 查询分区表记录： 
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; select * from dinya_test partition(part_01); <br />TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE <br />-------------------------------------------------------------------------------- <br />1 12 BOOKS 2005-1-14 14:19: <br />2 12 BOOKS 2005-2-13 14:19: <br />SQL&gt; <br />SQL&gt; select * from dinya_test partition(part_02); <br />TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE <br />-------------------------------------------------------------------------------- <br />3 12 BOOKS 2006-5-30 <br />4 12 BOOKS 2007-6-23 <br />SQL&gt; <br />SQL&gt; select * from dinya_test partition(part_03); <br />TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE <br />-------------------------------------------------------------------------------- <br />5 12 BOOKS 2011-2-26 <br />6 12 BOOKS 2011-4-30 <br />SQL&gt;</font></td></tr></tbody></table><br />　　 从查询的结果可以看出，插入的数据已经根据交易时间范围存储在不同的分区中。这里是指定了分区的查询，当然也可以不指定分区，直接执行select * from dinya_test查询全部记录。<br /><br />　　 在也检索的数据量很大的时候，指定分区会大大提高检索速度。 <br /><br />　　 1.2.3. 更新分区表的记录： <br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; update dinya_test partition(part_01) t set t.item_description=&#8217;DESK&#8217; where <br />t.transaction_id=1; <br />1 row updated. <br />SQL&gt; commit; <br />Commit complete. <br />SQL&gt;</font></td></tr></tbody></table><br />　　 这里将第一个分区中的交易ID=1的记录中的item_description字段更新为&#8220;DESK&#8221;，可以看到已经成功更新了一条记录。但是当更新的时候指定了分区，而根据查询的记录不在该分区中时，将不会更新数据，请看下面的例子： 
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; update dinya_test partition(part_01) t set t.item_description=&#8217;DESK&#8217; where <br />t.transaction_id=6; <br />0 rows updated. <br />SQL&gt; commit; <br />Commit complete. <br />SQL&gt;</font></td></tr></tbody></table><br />　　 指定了在第一个分区中更新记录，但是条件中限制交易ID为6，而查询全表，交易ID为6的记录在第三个分区中，这样该条语句将不会更新记录。 <br /><br />　　 1.2.4. 删除分区表记录： <br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; delete from dinya_test partition(part_02) t where t.transaction_id=4; <br />1 row deleted. <br />SQL&gt; commit; <br />Commit complete. <br />SQL&gt; </font></td></tr></tbody></table></p>
<p><br />　　 上面例子删除了第二个分区part_02中的交易记录ID为4的一条记录，和更新数据相同，如果指定了分区，而条件中的数据又不在该分区中时，将不会删除任何数据。</p><img src ="http://www.blogjava.net/tjyhy590/aggbug/366191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-12-12 22:56 <a href="http://www.blogjava.net/tjyhy590/archive/2011/12/12/366191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库分区表操作方法（一）</title><link>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366189.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Mon, 12 Dec 2011 14:55:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366189.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/366189.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/366189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/366189.html</trackback:ping><description><![CDATA[<strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 摘要</strong>：在大量业务数据处理的项目中，可以考虑使用分区表来提高应用系统的性能并方便数据管理，本文详细介绍了分区表的使用。 <br /><br />　　 在大型的企业应用或企业级的数据库应用中，要处理的数据量通常可以达到几十到几百GB，有的甚至可以到TB级。虽然存储介质和数据处理技术的发展也很快，但是仍然不能满足用户的需求，为了使用户的大量的数据在读写操作和查询中速度更快，Oracle提供了对表和索引进行分区的技术，以改善大型应用系统的性能。 <br /><br />　　 使用分区的优点： <br /><br />　　 &#183;增强可用性：如果表的某个分区出现故障，表在其他分区的数据仍然可用； <br /><br />　　 &#183;维护方便：如果表的某个分区出现故障，需要修复数据，只修复该分区即可； <br /><br />　　 &#183;均衡I/O：可以把不同的分区映射到磁盘以平衡I/O，改善整个系统性能； <br /><br />　　 &#183;改善查询性能：对分区对象的查询可以仅搜索自己关心的分区，提高检索速度。 <br /><br />　　 Oracle数据库提供对表或索引的分区方法有三种： <br /><br />　　 &#183;范围分区 <br /><br />　　 &#183;Hash分区（散列分区） <br /><br />　　 &#183;复合分区 <br /><br />　　 下面将以实例的方式分别对这三种分区方法来说明分区表的使用。为了测试方便，我们先建三个表空间。 <br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">create tablespace dinya_space01 <br />datafile &#8217;/test/demo/oracle/demodata/dinya01.dnf&#8217; size 50M <br />create tablespace dinya_space01 <br />datafile &#8217;/test/demo/oracle/demodata/dinya02.dnf&#8217; size 50M <br />create tablespace dinya_space01 <br />datafile &#8217;/test/demo/oracle/demodata/dinya03.dnf&#8217; size 50M</font></td></tr></tbody></table><br />　　<strong>1.1. 分区表的创建</strong> <br /><br />　　 1.1.1. 范围分区 <br /><br />　　 范围分区就是对数据表中的某个值的范围进行分区，根据某个值的范围，决定将该数据存储在哪个分区上。如根据序号分区，根据业务记录的创建日期进行分区等。 <br /><br />　　 需求描述：有一个物料交易表，表名：material_transactions。该表将来可能有千万级的数据记录数。要求在建该表的时候使用分区表。这时候我们可以使用序号分区三个区，每个区中预计存储三千万的数据，也可以使用日期分区，如每五年的数据存储在一个分区上。 <br /><br />　　 根据交易记录的序号分区建表： 
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; create table dinya_test <br />2 ( <br />3 transaction_id number primary key, <br />4 item_id number(8) not null, <br />5 item_description varchar2(300), <br />6 transaction_date date not null <br />7 ) <br />8 partition by range (transaction_id) <br />9 ( <br />10 partition part_01 values less than(30000000) tablespace dinya_space01, <br />11 partition part_02 values less than(60000000) tablespace dinya_space02, <br />12 partition part_03 values less than(maxvalue) tablespace dinya_space03 <br />13 ); <br />Table created.</font></td></tr></tbody></table>　　　 建表成功，根据交易的序号，交易ID在三千万以下的记录将存储在第一个表空间dinya_space01中，分区名为:par_01，在三千万到六千万之间的记录存储在第二个表空间：<br /><br />　　 dinya_space02中，分区名为：par_02，而交易ID在六千万以上的记录存储在第三个表空间dinya_space03中，分区名为par_03. <br /><br />　　 根据交易日期分区建表： <br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; create table dinya_test <br />2 ( <br />3 transaction_id number primary key, <br />4 item_id number(8) not null, <br /><br />5 item_description varchar2(300), <br />6 transaction_date date not null <br />7 ) <br />8 partition by range (transaction_date) <br />9 ( <br />10 partition part_01 values less than(to_date(&#8217;2006-01-01&#8217;,&#8217;yyyy-mm-dd&#8217;)) <br />tablespace dinya_space01, <br />11 partition part_02 values less than(to_date(&#8217;2010-01-01&#8217;,&#8217;yyyy-mm-dd&#8217;)) <br />tablespace dinya_space02, <br />12 partition part_03 values less than(maxvalue) tablespace dinya_space03 <br />13 ); <br />Table created.</font></td></tr></tbody></table>
<p><br />　　 这样我们就分别建了以交易序号和交易日期来分区的分区表。每次插入数据的时候，系统将根据指定的字段的值来自动将记录存储到制定的分区（表空间）中。 <br /><br />　　 当然，我们还可以根据需求，使用两个字段的范围分布来分区，如partition by range ( transaction_id ,transaction_date), 分区条件中的值也做相应的改变，请读者自行测试。 <br /></p><img src ="http://www.blogjava.net/tjyhy590/aggbug/366189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-12-12 22:55 <a href="http://www.blogjava.net/tjyhy590/archive/2011/12/12/366189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库分区表操作方法（二）</title><link>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366190.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Mon, 12 Dec 2011 14:55:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366190.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/366190.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/12/12/366190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/366190.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/366190.html</trackback:ping><description><![CDATA[1.1.2. Hash分区（散列分区） <br /><br />　　 散列分区为通过指定分区编号来均匀分布数据的一种分区类型，因为通过在I/O设备上进行散列分区，使得这些分区大小一致。如将物料交易表的数据根据交易ID散列地存放在指定的三个表空间中： <br /><br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; create table dinya_test <br />2 ( <br />3 transaction_id number primary key, <br />4 item_id number(8) not null, <br />5 item_description varchar2(300), <br />6 transaction_date date <br />7 ) <br />8 partition by hash(transaction_id) <br />9 ( <br />10 partition part_01 tablespace dinya_space01, <br />11 partition part_02 tablespace dinya_space02, <br />12 partition part_03 tablespace dinya_space03 <br />13 ); <br />Table created.</font></td></tr></tbody></table><br />　　 建表成功，此时插入数据，系统将按transaction_id将记录散列地插入三个分区中，这里也就是三个不同的表空间中。 <br /><br />　　 1.1.3. 复合分区 <br /><br />　　 有时候我们需要根据范围分区后，每个分区内的数据再散列地分布在几个表空间中，这样我们就要使用复合分区。复合分区是先使用范围分区，然后在每个分区内再使用散列分区的一种分区方法，如将物料交易的记录按时间分区，然后每个分区中的数据分三个子分区，将数据散列地存储在三个指定的表空间中： <br /><br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
<tbody>
<tr>
<td style="word-wrap: break-word" bgcolor="#fdfddf"><font color="#ff0000">以下为引用的内容：</font><br /><font face="新宋体">SQL&gt; create table dinya_test <br />2 ( <br />3 transaction_id number primary key, <br />4 item_id number(8) not null, <br />5 item_description varchar2(300), <br />6 transaction_date date <br />7 ) <br />8 partition by range(transaction_date)subpartition by hash(transaction_id) <br />9 subpartitions 3 store in (dinya_space01,dinya_space02,dinya_space03) <br />10 ( <br />11 partition part_01 values less than(to_date(&#8217;2006-01-01&#8217;,&#8217;yyyy-mm-dd&#8217;)), <br />12 partition part_02 values less than(to_date(&#8217;2010-01-01&#8217;,&#8217;yyyy-mm-dd&#8217;)), <br />13 partition part_03 values less than(maxvalue) <br />14 ); <br />Table created.</font></td></tr></tbody></table>
<p><br />　　 该例中，先是根据交易日期进行范围分区，然后根据交易的ID将记录散列地存储在三个表空间中。 </p><img src ="http://www.blogjava.net/tjyhy590/aggbug/366190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-12-12 22:55 <a href="http://www.blogjava.net/tjyhy590/archive/2011/12/12/366190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate继承映射(Inheritance Mappings)</title><link>http://www.blogjava.net/tjyhy590/archive/2011/11/26/364902.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Sat, 26 Nov 2011 15:52:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/11/26/364902.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/364902.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/11/26/364902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/364902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/364902.html</trackback:ping><description><![CDATA[三种策略 
<p>Hibernate支持三种基本的继承映射策略： </p>
<div class="itemizedlist">
<ul type="disc"><li>
<p>每个类分层结构一张表(table per class hierarchy) </p></li><li>
<p>每个子类一张表(table per subclass) </p></li><li>
<p>每个具体类一张表(table per concrete class) </p></li></ul></div>
<p>此外，Hibernate还支持第四种稍有不同的多态映射策略： </p>
<div class="itemizedlist">
<ul type="disc"><li>
<p>隐式多态(implicit polymorphism) </p></li></ul></div>
<p>对于同一个继承层次内的不同分支，可以采用不同的映射策略，然后用隐式多 态来完成跨越整个层次的多态。但是在同一个<code class="literal">&lt;class&gt;</code>根元素 下，Hibernate不支持混合了元素<code class="literal">&lt;subclass&gt;</code>、 <code class="literal">&lt;joined-subclass&gt;</code>和<code class="literal">&lt;union-subclass&gt;</code> 的映射。在同一个<code class="literal">&lt;class&gt;</code>元素下，可以混合使用 &#8220;每个类分层结构一张表&#8221;（table per hierarchy） 和&#8220;每个子类一张表&#8221;（table per subclass） 这两种映射策略，这是通过结合元素<code class="literal">&lt;subclass&gt;</code>和 <code class="literal">&lt;join&gt;</code>来实现的（见后）。 </p>
<p>在多个映射文件中，可以直接在<code class="literal">hibernate-mapping</code>根下定义<code class="literal">subclass</code>，<code class="literal">union-subclass</code>和<code class="literal">joined-subclass</code>。也就是说，你可以仅加入一个新的映射文件来扩展类层次。你必须在subclass的映射中指明<code class="literal">extends</code>属性，给出一个之前定义的超类的名字。注意，在以前，这一功能对映射文件的顺序有严格的要求，从Hibernate 3开始，使用extends关键字的时侯，对映射文件的顺序不再有要求；但在每个映射文件里，超类必须在子类之前定义。 </p><pre class="programlisting"> &lt;hibernate-mapping&gt;
     &lt;subclass name="DomesticCat" extends="Cat" discriminator-value="D"&gt;
          &lt;property name="name" type="string"/&gt;
     &lt;/subclass&gt;
 &lt;/hibernate-mapping&gt;</pre>
<div class="sect2" lang="zh-cn">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="inheritance-tableperclass"></a>9.1.1.&nbsp;每个类分层结构一张表(Table per class hierarchy)</h3></div></div></div>
<p>假设我们有接口<code class="literal">Payment</code>和它的几个实现类： <code class="literal">CreditCardPayment</code>, <code class="literal">CashPayment</code>, 和<code class="literal">ChequePayment</code>。则&#8220;每个类分层结构一张表&#8221;(Table per class hierarchy)的映射代码如下所示： </p><pre class="programlisting">&lt;class name="Payment" table="PAYMENT"&gt;
    &lt;id name="id" type="long" column="PAYMENT_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    &lt;discriminator column="PAYMENT_TYPE" type="string"/&gt;
    &lt;property name="amount" column="AMOUNT"/&gt;
    ...
    &lt;subclass name="CreditCardPayment" discriminator-value="CREDIT"&gt;
        &lt;property name="creditCardType" column="CCTYPE"/&gt;
        ...
    &lt;/subclass&gt;
    &lt;subclass name="CashPayment" discriminator-value="CASH"&gt;
        ...
    &lt;/subclass&gt;
    &lt;subclass name="ChequePayment" discriminator-value="CHEQUE"&gt;
        ...
    &lt;/subclass&gt;
&lt;/class&gt;</pre>
<p>采用这种策略只需要一张表即可。它有一个很大的限制：要求那些由子类定义的字段， 如<code class="literal">CCTYPE</code>，不能有<code class="literal">非空(NOT NULL)</code>约束。 </p></div>
<div class="sect2" lang="zh-cn">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="inheritance-tablepersubclass"></a>9.1.2.&nbsp;每个子类一张表(Table per subclass)</h3></div></div></div>
<p>对于上例中的几个类而言，采用&#8220;每个子类一张表&#8221;的映射策略，代码如下所示： </p><pre class="programlisting">&lt;class name="Payment" table="PAYMENT"&gt;
    &lt;id name="id" type="long" column="PAYMENT_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    &lt;property name="amount" column="AMOUNT"/&gt;
    ...
    &lt;joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"&gt;
        &lt;key column="PAYMENT_ID"/&gt;
        ...
    &lt;/joined-subclass&gt;
    &lt;joined-subclass name="CashPayment" table="CASH_PAYMENT"&gt;
        &lt;key column="PAYMENT_ID"/&gt;
        &lt;property name="creditCardType" column="CCTYPE"/&gt;
        ...
    &lt;/joined-subclass&gt;
    &lt;joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT"&gt;
        &lt;key column="PAYMENT_ID"/&gt;
        ...
    &lt;/joined-subclass&gt;
&lt;/class&gt;</pre>
<p>需要四张表。三个子类表通过主键关联到超类表(因而关系模型实际上是一对一关联)。 </p></div>
<div class="sect2" lang="zh-cn">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="inheritance-tablepersubclass-discriminator"></a>9.1.3.&nbsp;每个子类一张表(Table per subclass)，使用辨别标志(Discriminator)</h3></div></div></div>
<p>注意，对&#8220;每个子类一张表&#8221;的映射策略，Hibernate的实现不需要辨别字段，而其他 的对象/关系映射工具使用了一种不同于Hibernate的实现方法，该方法要求在超类 表中有一个类型辨别字段(type discriminator column)。Hibernate采用的方法更 难实现，但从关系（数据库）的角度来看，按理说它更正确。若你愿意使用带有辨别字 段的&#8220;每个子类一张表&#8221;的策略，你可以结合使用<code class="literal">&lt;subclass&gt;</code> 与<code class="literal">&lt;join&gt;</code>，如下所示： </p><pre class="programlisting">&lt;class name="Payment" table="PAYMENT"&gt;
    &lt;id name="id" type="long" column="PAYMENT_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    &lt;discriminator column="PAYMENT_TYPE" type="string"/&gt;
    &lt;property name="amount" column="AMOUNT"/&gt;
    ...
    &lt;subclass name="CreditCardPayment" discriminator-value="CREDIT"&gt;
        &lt;join table="CREDIT_PAYMENT"&gt;
            &lt;key column="PAYMENT_ID"/&gt;
            &lt;property name="creditCardType" column="CCTYPE"/&gt;
            ...
        &lt;/join&gt;
    &lt;/subclass&gt;
    &lt;subclass name="CashPayment" discriminator-value="CASH"&gt;
        &lt;join table="CASH_PAYMENT"&gt;
            &lt;key column="PAYMENT_ID"/&gt;
            ...
        &lt;/join&gt;
    &lt;/subclass&gt;
    &lt;subclass name="ChequePayment" discriminator-value="CHEQUE"&gt;
        &lt;join table="CHEQUE_PAYMENT" fetch="select"&gt;
            &lt;key column="PAYMENT_ID"/&gt;
            ...
        &lt;/join&gt;
    &lt;/subclass&gt;
&lt;/class&gt;</pre>
<p>可选的声明<code class="literal">fetch="select"</code>，是用来告诉Hibernate，在查询超类时， 不要使用外部连接(outer join)来抓取子类<code class="literal">ChequePayment</code>的数据。 </p></div>
<div class="sect2" lang="zh-cn">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="inheritance-mixing-tableperclass-tablepersubclass"></a>9.1.4.&nbsp;混合使用&#8220;每个类分层结构一张表&#8221;和&#8220;每个子类一张表&#8221;</h3></div></div></div>
<p>你甚至可以采取如下方法混和使用&#8220;每个类分层结构一张表&#8221;和&#8220;每个子类一张表&#8221;这两种策略： </p><pre class="programlisting">&lt;class name="Payment" table="PAYMENT"&gt;
    &lt;id name="id" type="long" column="PAYMENT_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    &lt;discriminator column="PAYMENT_TYPE" type="string"/&gt;
    &lt;property name="amount" column="AMOUNT"/&gt;
    ...
    &lt;subclass name="CreditCardPayment" discriminator-value="CREDIT"&gt;
        &lt;join table="CREDIT_PAYMENT"&gt;
            &lt;property name="creditCardType" column="CCTYPE"/&gt;
            ...
        &lt;/join&gt;
    &lt;/subclass&gt;
    &lt;subclass name="CashPayment" discriminator-value="CASH"&gt;
        ...
    &lt;/subclass&gt;
    &lt;subclass name="ChequePayment" discriminator-value="CHEQUE"&gt;
        ...
    &lt;/subclass&gt;
&lt;/class&gt;</pre>
<p>对上述任何一种映射策略而言，指向根类<code class="literal">Payment</code>的 关联是使用<code class="literal">&lt;many-to-one&gt;</code>进行映射的。 </p><pre class="programlisting">&lt;many-to-one name="payment" column="PAYMENT_ID" class="Payment"/&gt;</pre></div>
<div class="sect2" lang="zh-cn">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="inheritance-tableperconcrete"></a>9.1.5.&nbsp;每个具体类一张表(Table per concrete class)</h3></div></div></div>
<p>对于&#8220;每个具体类一张表&#8221;的映射策略，可以采用两种方法。第一种方法是使用 <code class="literal">&lt;union-subclass&gt;</code>。 </p><pre class="programlisting">&lt;class name="Payment"&gt;
    &lt;id name="id" type="long" column="PAYMENT_ID"&gt;
        &lt;generator class="sequence"/&gt;
    &lt;/id&gt;
    &lt;property name="amount" column="AMOUNT"/&gt;
    ...
    &lt;union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"&gt;
        &lt;property name="creditCardType" column="CCTYPE"/&gt;
        ...
    &lt;/union-subclass&gt;
    &lt;union-subclass name="CashPayment" table="CASH_PAYMENT"&gt;
        ...
    &lt;/union-subclass&gt;
    &lt;union-subclass name="ChequePayment" table="CHEQUE_PAYMENT"&gt;
        ...
    &lt;/union-subclass&gt;
&lt;/class&gt;</pre>
<p>这里涉及三张与子类相关的表。每张表为对应类的所有属性（包括从超类继承的属性）定义相应字段。 </p>
<p>这种方式的局限在于，如果一个属性在超类中做了映射，其字段名必须与所有子类 表中定义的相同。(我们可能会在Hibernate的后续发布版本中放宽此限制。) 不允许在联合子类(union subclass)的继承层次中使用标识生成器策略(identity generator strategy), 实际上, 主键的种子(primary key seed)不得不为同一继承层次中的全部被联合子类所共用. </p>
<p>假若超类是抽象类，请使用<code class="literal">abstract="true"</code>。当然，假若它不是抽象的，需要一个额外的表（上面的例子中，默认是<code class="literal">PAYMENT</code>），来保存超类的实例。 </p></div>
<div class="sect2" lang="zh-cn">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="inheritance-tableperconcreate-polymorphism"></a>9.1.6.&nbsp;Table per concrete class, using implicit polymorphism</h3></div>
<div>
<h3 class="title"><a name="inheritance-tableperconcreate-polymorphism"></a>9.1.6.&nbsp;Table per concrete class, using implicit polymorphism</h3></div></div></div>
<p>另一种可供选择的方法是采用隐式多态： </p><pre class="programlisting">&lt;class name="CreditCardPayment" table="CREDIT_PAYMENT"&gt;
    &lt;id name="id" type="long" column="CREDIT_PAYMENT_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    &lt;property name="amount" column="CREDIT_AMOUNT"/&gt;
    ...
&lt;/class&gt;

&lt;class name="CashPayment" table="CASH_PAYMENT"&gt;
    &lt;id name="id" type="long" column="CASH_PAYMENT_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    &lt;property name="amount" column="CASH_AMOUNT"/&gt;
    ...
&lt;/class&gt;

&lt;class name="ChequePayment" table="CHEQUE_PAYMENT"&gt;
    &lt;id name="id" type="long" column="CHEQUE_PAYMENT_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    &lt;property name="amount" column="CHEQUE_AMOUNT"/&gt;
    ...
&lt;/class&gt;</pre>
<p>注意，我们没有在任何地方明确的提及接口<code class="literal">Payment</code>。同时注意 <code class="literal">Payment</code>的属性在每个子类中都进行了映射。如果你想避免重复， 可以考虑使用XML实体(例如：位于<code class="literal">DOCTYPE</code>声明内的 <code class="literal">[ &lt;!ENTITY allproperties SYSTEM "allproperties.xml"&gt; ]</code> 和映射中的<code class="literal">&amp;allproperties;</code>)。 </p>
<p>这种方法的缺陷在于，在Hibernate执行多态查询时(polymorphic queries)无法生成带 <code class="literal">UNION</code>的SQL语句。 </p>
<p>对于这种映射策略而言，通常用<code class="literal">&lt;any&gt;</code>来实现到 <code class="literal">Payment</code>的多态关联映射。 </p><pre class="programlisting">&lt;any name="payment" meta-type="string" id-type="long"&gt;
    &lt;meta-value value="CREDIT" class="CreditCardPayment"/&gt;
    &lt;meta-value value="CASH" class="CashPayment"/&gt;
    &lt;meta-value value="CHEQUE" class="ChequePayment"/&gt;
    &lt;column name="PAYMENT_CLASS"/&gt;
    &lt;column name="PAYMENT_ID"/&gt;
&lt;/any&gt;</pre></div>
<div class="sect2" lang="zh-cn">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="inheritace-mixingpolymorphism"></a>9.1.7.&nbsp;隐式多态和其他继承映射混合使用</h3></div></div></div>
<p>对这一映射还有一点需要注意。因为每个子类都在各自独立的元素<code class="literal">&lt;class&gt;</code> 中映射(并且<code class="literal">Payment</code>只是一个接口)，每个子类可以很容易的成为另一 个继承体系中的一部分！(你仍然可以对接口<code class="literal">Payment</code>使用多态查询。) </p><pre class="programlisting">&lt;class name="CreditCardPayment" table="CREDIT_PAYMENT"&gt;
    &lt;id name="id" type="long" column="CREDIT_PAYMENT_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    &lt;discriminator column="CREDIT_CARD" type="string"/&gt;
    &lt;property name="amount" column="CREDIT_AMOUNT"/&gt;
    ...
    &lt;subclass name="MasterCardPayment" discriminator-value="MDC"/&gt;
    &lt;subclass name="VisaPayment" discriminator-value="VISA"/&gt;
&lt;/class&gt;

&lt;class name="NonelectronicTransaction" table="NONELECTRONIC_TXN"&gt;
    &lt;id name="id" type="long" column="TXN_ID"&gt;
        &lt;generator class="native"/&gt;
    &lt;/id&gt;
    ...
    &lt;joined-subclass name="CashPayment" table="CASH_PAYMENT"&gt;
        &lt;key column="PAYMENT_ID"/&gt;
        &lt;property name="amount" column="CASH_AMOUNT"/&gt;
        ...
    &lt;/joined-subclass&gt;
    &lt;joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT"&gt;
        &lt;key column="PAYMENT_ID"/&gt;
        &lt;property name="amount" column="CHEQUE_AMOUNT"/&gt;
        ...
    &lt;/joined-subclass&gt;
&lt;/class&gt;</pre>
<p>我们还是没有明确的提到<code class="literal">Payment</code>。 如果我们针对接口<code class="literal">Payment</code>执行查询 &#8212;&#8212;如<code class="literal">from Payment</code>&#8212;&#8212; Hibernate 自动返回<code class="literal">CreditCardPayment</code>(和它的子类，因为 它们也实现了接口<code class="literal">Payment</code>)、 <code class="literal">CashPayment</code>和<code class="literal">Chequepayment</code>的实例， 但不返回<code class="literal">NonelectronicTransaction</code>的实例。 </p></div><img src ="http://www.blogjava.net/tjyhy590/aggbug/364902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-11-26 23:52 <a href="http://www.blogjava.net/tjyhy590/archive/2011/11/26/364902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JVM优化配置</title><link>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362192.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Thu, 27 Oct 2011 11:32:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362192.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/362192.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/362192.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/362192.html</trackback:ping><description><![CDATA[<p><font size="5"><span style="font-size: 12pt; line-height: 173%">&nbsp;</p>
<div><font size="5"><span style="font-size: 12pt; line-height: 173%">JVM</span><span style="font-size: 12pt; line-height: 173%">优化配置</span></font><font size="5"><span style="font-size: 12pt; line-height: 173%">《一》</span></font><br /><font size="5"><span style="font-size: 12pt; line-height: 173%"><br /></span></font><span>OOM</span>这个缩写就是Java程序开发过程中让人最头痛的问题：Out of Memory。在很多开发人员的开发过程中，或多或少的都会遇到这类问题，这类问题定位比较困难，往往需要根据经验来判断可能出现问题的代码。原因主要是 两个：对象没有被释放（多种情况引起，往往是比较隐蔽的引用导致被Hold而无法被回收）。另一种就是真的Memory不够用了，需要增加JVM的 Heap来满足应用程序的需求。最近有同事发的关于解决OOM的问题，让我了解了原来OOM除了在JVM Heap不够时会发生，在Native Heap不够的时候也会发生，同时JVM Heap和Native Heap存在着相互影响和平衡的关系，因此就仔细的去看了关于OOM和JVM配置优化的内容。 
<div></div>
<div><font size="5"><span style="font-size: 12pt; line-height: 173%">OOM</span></font></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在 其他语言类似于C,Delphi等等由于内存都是由自己分配和管理，因此内存泄露的问题比较常见，同时也是很头痛的一件事情。而Java的对象生命周期管 理都是JVM来做的，简化了开发人员的非业务逻辑的处理，但是这种自动管理回收机制也是基于一些规则的，而违背了这些规则的时候，就会造成所谓的 &#8220;Memory Leak&#8221;。</div>
<div></div>
<div>OOM(Java Heap)</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>错误提示：java.lang.OutOfMemoryError。</div>
<div style="text-indent: 21pt">这 类OOM是由于JVM分配的给应用的Heap Memory已经被耗尽，可能是因为应用在高负荷的情况下的却需要很大的内存，因此可以通过修改JVM参数来增加Java Heap Memory（不过也不能无限制增加，后面那种OOM有可能就是因为这个原因而产生）。另一种情况是因为应用程序使用对象或者资源没有释放，导致内存消耗 持续增加，最后出现OOM，这类问题引起的原因往往是应用已不需要的对象还被其他有效对象所引用，那么就无法释放，可能是业务代码逻辑造成的（异常处理不 够例如IO等资源），也可能是对于第三方开源项目中资源释放了解不够导致使用以后资源没有释放（例如JDBC的ResultSet等）。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>几个容易出现问题的场景：</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1</span>．应用的缓存或者Collection：如果应用要缓存Java对象或者是在一个Collection中保存对象，那么就要确定是否会有大量的对象存入，要做保护，以防止在大数据量下大量内存被消耗，同时要保证Cache的大小不会无限制增加。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2</span>．生命周期较长的对象：尽量简短对象的生命周期，现在采用对象的创建释放代价已经很低，同时作了很好的优化，要比创建一个对象长期反复使用要好。如果能够设置超时的情景下，尽量设置超时。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3</span>．类似于JDBC的Connection Pool，在使用Pool中的对象以后需要释放并返回，不然就会造成Pool的不断增大，在其他Pool中使用也是一样。同样ResultSet，IO这类资源的释放都需要注意。</div>
<div></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>解决的方法就是查找错误或者是增加Java Heap Memory。对于此类问题检测工具相当多，这里就不做介绍了。<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></div>
<div></div>
<div></div>
<div>OOM(Native Heap)</div>
<div style="text-indent: 21pt">错误提示：requested XXXX bytes for ChunkPool::allocate. Out of swap space。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Native Heap Memory</span>是JVM 内部使用的Memory，这部分的Memory可以通过JDK提供的JNI的方式去访问，这部分Memory效率很高，但是管理需要自己去做，如果没有把 握最好不要使用，以防出现内存泄露问题。JVM 使用Native Heap Memory用来优化代码载入（JTI代码生成），临时对象空间申请，以及JVM内部的一些操作。这次同事在压力测试中遇到的问题就是这类OOM，也就是 这类Memory耗尽。同样这类OOM产生的问题也是分成正常使用耗尽和无释放资源耗尽两类。无释放资源耗尽很多时候不是程序员自身的原因，可能是引用的 第三方包的缺陷，例如很多人遇到的Oracle 9 JDBC驱动在低版本中有内存泄露的问题。要确定这类问题，就需要去观察Native Heap Memory的增长和使用情况，在服务器应用起来以后，运行一段时间后JVM对于Native Heap Memory的使用会达到一个稳定的阶段，此时可以看看什么操作对于Native Heap Memory操作频繁，而且使得Native Heap Memory增长，对于Native Heap Memory的情况我还没有找到办法去检测，现在能够看到的就是为JVM启动时候增加-verbose:jni参数来观察对于Native Heap Memory的操作。另一种情况就是正常消耗Native Heap Memory，对于Native Heap Memory的使用主要取决于JVM代码生成，线程创建，用于优化的临时代码和对象产生。当正常耗尽Native Heap Memory时，那么就需要增加Native Heap Memory，此时就会和我们前面提到增加java Heap Memory的情况出现矛盾。</div>
<div></div>
<div>应用内存组合</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>对 于应用来说，可分配的内存受到OS的限制，不同的OS对进程所能访问虚拟内存地址区间直接影响对于应用内存的分配，32位的操作系统通常最大支持4G的内 存寻址，而Linux一般为3G，Windows为2G。然而这些大小的内存并不会全部给JVM的Java Heap使用，它主要会分成三部分：Java Heap，Native Heap，载入资源和类库等所占用的内存。那么由此可见，Native Heap和 Java Heap大小配置是相互制约的，哪一部分分配多了都可能会影响到另外一部分的正常工作，因此如果通过命令行去配置，那么需要确切的了解应用使用情况，否则 采用默认配置自动监测会更好的优化应用使用情况。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>同样要注意的就是进程的虚拟内存和机器的实际内存还是有区别的，对于机器来说实际内存以及硬盘提供的虚拟内存都是提供给机器上所有进程使用的，因此在设置JVM参数时，它的虚拟内存绝对不应该超过实际内存的大小。<br /><font size="5"><span style="font-size: 12pt; line-height: 173%">《二》</span></font></div></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>这 里首先要说明的是这里提到的JVM是Sun的HotSpot JVM 5和以上的版本。性能优化在应用方面可以有很多手段，包括Cache，多线程，各种算法等等。通常情况下是不建议在没有任何统计和分析的情况下去手动配置 JVM的参数来调整性能，因为在JVM 5以上已经作了根据机器和OS的情况自动配置合适参数的算法，基本能够满足大部分的情况，当然这种自动适配只是一种通用的方式，如果说真的要达到最优，那 么还是需要根据实际的使用情况来手动的配置各种参数设置，提高性能。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JVM</span>能够对性能产生影响的最大部分就是对于内存的管理。从jdk 1.5以后内存管理和分配有了很多的改善和提高。</div>
<div><font size="4"><span style="font-size: 10.5pt; line-height: 173%">内存分配以及管理的几个基本概念和参数说明：</span></font></div>
<div>Java Hotspot Mode：</div>
<div style="text-indent: 21pt">server 和 client两种模式，如果不配置，JVM会根据应用服务器硬件配置自动选择模式，server模式启动比较慢，但是运行期速度得到了优化，client启动比较快，但是运行期响应没有server模式的优化，适合于个人PC的服务开发和测试。</div>
<div></div>
<div>Garbage Collector Policy：</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在Jdk 1.5的时候已经提供了三种GC，除了原来提供的串行GC（SerialGC）以外，还提供了两种新的GC：ParallelGC和 ConcMarkSweepGC。ParallelGC采用了多线程并行管理和回收垃圾对象，提高了回收效率，提高了服务器的吞吐量，适合于多处理器的服 务器。ConcMarkSweepGC采用的是并发方式来管理和回收垃圾对象，降低垃圾回收产生的响应暂停时间。这里说一下并发和并行的区别，并发指的是 多个进程并行执行垃圾回收，那么可以很好的利用多处理器，而并行指的是应用程序不需要暂停可以和垃圾回收线程并发工作。串行GC适合小型应用和单处理器系 统（无需多线程交互，效率比较高），后两者适合大型系统。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>使用方式就是在参数配置中增加-XX:+UseParallelGC等方式来设置。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>对于这部分的配置在网上有很多的实例可以参考，不过最终采用哪一种GC还是要根据具体的情况来分析和选择。</div>
<div></div>
<div>Heap：</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OOM</span>的 各种经历已经让每一个架构师开发人员看到了了解Heap的重要性。OOM已经是Heap的临界点，不得不引起注意，然而Heap对于性能的潜在影响并未被 引起重视，不过和GC配置一样，在没有对使用情况作仔细分析和研究的情况下，贸然的去修改Heap配置，可能适得其反，这里就来看一下Heap的一些概念 和对于性能的影响。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>我们的应用所能够得到的最大的Heap受三部分因素的制约：数据处理 模型（32位或者64位操作系统），系统地虚拟内存总数和系统的物理内存总数。首先Heap的大小不能超过不同操作系统的进程寻址范围，当前大部分系统最 高限度是4G，Windows通常是2G，Linux通常是3G。系统的虚拟内存也是分配的依据，首先是不能超过，然后由于操作系统支持硬盘来做部分的虚 拟内存，如果设置过大，那么对于应用响应来说势必有影响。再则就是要考虑同一台服务器上运行多个Java虚拟机所消耗的资源总合也不能超过可用资源。就和 前面OOM分析中的一样，其实由于OS的数据处理模型的限制，机器本身的硬件内存资源和虚拟内存资源并不一定会匹配，那么在有限的资源下如何调整好资源分 配，对于应用来说尤为重要。</div>
<div></div>
<div></div>
<div>关于Heap的几个参数设置：</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>说了Heap的有限资源问题以后，就来看看如何通过配置去改变JVM对于Heap的分配。下面所说的主要是对于Java Heap的分配，那么在申请了Java Heap以后，剩下的可用资源就会被使用到Native Heap。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Xms: java heap</span>初始化时的大小。默认情况是机器物理内存的1/64。这个主要是根据应用启动时消耗的资源决定，分配少了申请起来会降低启动速度，分配多了也浪费。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Xmx:java heap</span>的 最大值，默认是机器物理内存的1/4，最大也就到1G。这个值决定了最多可用的Java Heap Memory，分配过少就会在应用需要大量内存作缓存或者零时对象时出现OOM的问题，如果分配过大，那么就会产生上文提到的第二类OOM。所以如何配置 还是根据运行过程中的分析和计算来确定，如果不能确定还是采用默认的配置。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Xmn:java heap</span>新 生代的空间大小。在GC模型中，根据对象的生命周期的长短，产生了内存分代的设计：青年代（内部也分成三部分，类似于整体划分的作用，可以通过配置来设置 比例），老年代，持久代。每一代的管理和回收策略都不相同，最为活跃的就是青年代，同时这部分的内存分配和管理效率也是最高。通常情况下，对于内存的申请 优先在新生代中申请，当内存不够时会整理新生代，当整理以后还是不能满足申请的内存，就会向老年代移动一些生命周期较长的对象。这种整理和移动会消耗资 源，同时降低系统运行响应能力，因此如果青年代设置的过小，就会频繁的整理和移动，对性能造成影响。那是否把年青代设置的越大越好，其实不然，年青代采用 的是复制搜集算法，这种算法必须停止所有应用程序线程，服务器线程切换时间就会成为应用响应的瓶颈（当然永远不用收集那么就不存在这个问题）。老年代采用 的是串行标记收集的方式，并发收集可以减少对于应用的影响。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Xss:</span>线程堆栈最大值。允许更多的虚拟内存空间地址被Java Heap使用。</div>
<div></div>
<div>以下是sun公司的性能优化白皮书中提到的几个例子：</div>
<div></div>
<div>1．对于吞吐量的调优。机器配置：4G的内存，32个线程并发能力。</div>
<div style="text-indent: 21pt"><code>java</code><code> -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20</code></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><code>-Xmx3800m -Xms3800m </code>配置了最大Java Heap来充分利用系统内存。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><code>-Xmn2g </code><code>创建足够大的青年代（可以并行被回收）充分利用系统内存，防止将短期对象复制到老年代。</code></div>
<div><code><span>&nbsp;&nbsp;&nbsp; -Xss128 </span></code><code>减少默认最大的线程栈大小，提供更多的处理虚拟内存地址空间被进程使用。</code></div>
<div><code><span>&nbsp;&nbsp;&nbsp; -XX:+UseParallelGC </span></code><code>采用并行垃圾收集器对年青代的内存进行收集，提高效率。</code></div>
<div><code><span>&nbsp;&nbsp;&nbsp; -XX:ParallelGCThreads=20 </span></code><code>减少垃圾收集线程，默认是和服务器可支持的线程最大并发数相同，往往不需要配置到最大值。</code></div>
<div><code></code></div>
<div><code>2</code><code>．尝试采用对老年代并行收集</code></div>
<div style="text-indent: 21pt"><code>java</code><code> -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC</code></div>
<div style="text-indent: 21pt"><code>-Xmx3550m -Xms3550m </code><code>内存分配被减小，因为<span>ParallelOldGC会增加对于Native Heap的需求，因此需要减小Java Heap来满足需求。</span></code></div>
<div style="text-indent: 21pt"><code>-XX:+UseParallelOldGC </code><code>采用对于老年代并发收集的策略，可以提高收集效率。</code></div>
<div><code></code></div>
<div><code>3</code><code>．提高吞吐量，减少应用停顿时间</code></div>
<div style="text-indent: 21pt"><code>java</code><code> -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31</code></div>
<div><code></code></div>
<div><code>-XX:+UseConcMarkSweepGC -XX:+UseParNewGC </code><code>选择了并发标记交换收集器，它可以并发执行收集操作，降低应用停止时间，同时它也是并行处理模式，可以有效地利用多处理器的系统的多进程处理。</code></div>
<div></div>
<div><code>-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=31 </code><code>表示在青年代中<span>Eden和Survivor比例，设置增加了Survivor的大小，越大的survivor空间可以允许短期对象尽量在年青代消亡。</span></code></div>
<div><code></code></div>
<div><code>-XX:TargetSurvivorRatio=90 </code><code>允许<span>90%的空间被占用，超过默认的50%，提高对于survivor的使用率。</span></code></div>
<div><code></code></div>
<div style="text-indent: 21pt"><code>类似的例子网上很多，这儿就不在列下来了，最终是否采取自己配置来替换默认配置还是要根据虚拟机的使用情况来分析和配置。<br /></code></div>
<p></span></font>&nbsp;</p><img src ="http://www.blogjava.net/tjyhy590/aggbug/362192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-10-27 19:32 <a href="http://www.blogjava.net/tjyhy590/archive/2011/10/27/362192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring事务配置的五种方式</title><link>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362191.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Thu, 27 Oct 2011 11:29:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362191.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/362191.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362191.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/362191.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/362191.html</trackback:ping><description><![CDATA[Spring配置文件中关于事务配置总是由三个组成部分，分别是DataSource、TransactionManager和代理机制这三部分，无论哪种配置方式，一般变化的只是代理机制这部分。 
<p>&nbsp;&nbsp;&nbsp; DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化，比如使用Hibernate进行数据访问时，DataSource实际为SessionFactory，TransactionManager的实现为HibernateTransactionManager。</p>
<p>&nbsp;&nbsp;&nbsp; 具体如下图：</p>
<p><a href="http://www.blogjava.net/images/blogjava_net/robbie/WindowsLiveWriter/Spring_9C9C/Spring%E4%BA%8B%E5%8A%A1%E9%85%8D%E7%BD%AE%20(2).jpg"><img height="378" alt="Spring事务配置 (2)" src="http://www.blogjava.net/images/blogjava_net/robbie/WindowsLiveWriter/Spring_9C9C/Spring%E4%BA%8B%E5%8A%A1%E9%85%8D%E7%BD%AE%20(2)_thumb.jpg" width="654" border="0" /></a></p>
<p>&nbsp;&nbsp;&nbsp; 根据代理机制的不同，总结了五种Spring事务的配置方式，配置文件如下：</p>
<p>&nbsp;&nbsp;&nbsp; 第一种方式：每个Bean都有一个代理</p>
<div><!--</p>
<p>Code highlighting produced by Actipro CodeHighlighter (freeware)</p>
<p>http://www.CodeHighlighter.com/</p>
<p>-->&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-8&#8243;?&gt;<br />&lt;beans xmlns=&#8221;http://www.springframework.org/schema/beans&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:xsi=&#8221;http://www.w3.org/2001/XMLSchema-instance&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:context=&#8221;http://www.springframework.org/schema/context&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:aop=&#8221;http://www.springframework.org/schema/aop&#8221;<br />&nbsp;&nbsp;&nbsp; xsi:schemaLocation=&#8221;http://www.springframework.org/schema/beans<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context/spring-context-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd&#8221;&gt; 
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;sessionFactory&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.LocalSessionFactoryBean&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configLocation&#8221; value=&#8221;classpath:hibernate.cfg.xml&#8221;&nbsp;/&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configurationClass&#8221; value=&#8221;org.hibernate.cfg.AnnotationConfiguration&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;!&#8211; 定义事务管理器（声明式的事务） &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;transactionManager&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.HibernateTransactionManager&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;sessionFactory&#8221; ref=&#8221;sessionFactory&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;!&#8211; 配置DAO &#8211;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;userDaoTarget&#8221; class=&#8221;com.bluesky.spring.dao.UserDaoImpl&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;sessionFactory&#8221; ref=&#8221;sessionFactory&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;userDao&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.transaction.interceptor.TransactionProxyFactoryBean&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; 配置事务管理器 &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;transactionManager&#8221; ref=&#8221;transactionManager&#8221;&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;target&#8221; ref=&#8221;userDaoTarget&#8221;&nbsp;/&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;proxyInterfaces&#8221; value=&#8221;com.bluesky.spring.dao.GeneratorDao&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; 配置事务属性 &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;transactionAttributes&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;props&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key=&#8221;*&#8221;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/props&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;<br />&lt;/beans&gt;</p></div>
<p>&nbsp;&nbsp;&nbsp; 第二种方式：所有Bean共享一个代理基类</p>
<div><!--</p>
<p>Code highlighting produced by Actipro CodeHighlighter (freeware)</p>
<p>http://www.CodeHighlighter.com/</p>
<p>-->&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-8&#8243;?&gt;<br />&lt;beans xmlns=&#8221;http://www.springframework.org/schema/beans&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:xsi=&#8221;http://www.w3.org/2001/XMLSchema-instance&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:context=&#8221;http://www.springframework.org/schema/context&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:aop=&#8221;http://www.springframework.org/schema/aop&#8221;<br />&nbsp;&nbsp;&nbsp; xsi:schemaLocation=&#8221;http://www.springframework.org/schema/beans<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context/spring-context-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd&#8221;&gt; 
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;sessionFactory&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.LocalSessionFactoryBean&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configLocation&#8221; value=&#8221;classpath:hibernate.cfg.xml&#8221;&nbsp;/&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configurationClass&#8221; value=&#8221;org.hibernate.cfg.AnnotationConfiguration&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;!&#8211; 定义事务管理器（声明式的事务） &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;transactionManager&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.HibernateTransactionManager&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;sessionFactory&#8221; ref=&#8221;sessionFactory&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;transactionBase&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.transaction.interceptor.TransactionProxyFactoryBean&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lazy-init=&#8221;true&#8221; abstract=&#8221;true&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; 配置事务管理器 &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;transactionManager&#8221; ref=&#8221;transactionManager&#8221;&nbsp;/&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; 配置事务属性 &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;transactionAttributes&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;props&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key=&#8221;*&#8221;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/props&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;!&#8211; 配置DAO &#8211;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;userDaoTarget&#8221; class=&#8221;com.bluesky.spring.dao.UserDaoImpl&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;sessionFactory&#8221; ref=&#8221;sessionFactory&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;userDao&#8221; parent=&#8221;transactionBase&#8221;&nbsp;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;target&#8221; ref=&#8221;userDaoTarget&#8221;&nbsp;/&gt;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&lt;/beans&gt;</p></div>
<p>第三种方式：使用拦截器</p>
<div><!--</p>
<p>Code highlighting produced by Actipro CodeHighlighter (freeware)</p>
<p>http://www.CodeHighlighter.com/</p>
<p>-->&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-8&#8243;?&gt;<br />&lt;beans xmlns=&#8221;http://www.springframework.org/schema/beans&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:xsi=&#8221;http://www.w3.org/2001/XMLSchema-instance&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:context=&#8221;http://www.springframework.org/schema/context&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:aop=&#8221;http://www.springframework.org/schema/aop&#8221;<br />&nbsp;&nbsp;&nbsp; xsi:schemaLocation=&#8221;http://www.springframework.org/schema/beans<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context/spring-context-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd&#8221;&gt; 
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;sessionFactory&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.LocalSessionFactoryBean&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configLocation&#8221; value=&#8221;classpath:hibernate.cfg.xml&#8221;&nbsp;/&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configurationClass&#8221; value=&#8221;org.hibernate.cfg.AnnotationConfiguration&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;!&#8211; 定义事务管理器（声明式的事务） &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;transactionManager&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.HibernateTransactionManager&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;sessionFactory&#8221; ref=&#8221;sessionFactory&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;transactionInterceptor&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.transaction.interceptor.TransactionInterceptor&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;transactionManager&#8221; ref=&#8221;transactionManager&#8221;&nbsp;/&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; 配置事务属性 &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;transactionAttributes&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;props&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key=&#8221;*&#8221;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/props&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean class=&#8221;org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;beanNames&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;*Dao&lt;/value&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/list&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;interceptorNames&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;transactionInterceptor&lt;/value&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/list&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;!&#8211; 配置DAO &#8211;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;userDao&#8221; class=&#8221;com.bluesky.spring.dao.UserDaoImpl&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;sessionFactory&#8221; ref=&#8221;sessionFactory&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&lt;/beans&gt;</p></div>
<p>第四种方式：使用tx标签配置的拦截器</p>
<div><!--</p>
<p>Code highlighting produced by Actipro CodeHighlighter (freeware)</p>
<p>http://www.CodeHighlighter.com/</p>
<p>-->&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-8&#8243;?&gt;<br />&lt;beans xmlns=&#8221;http://www.springframework.org/schema/beans&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:xsi=&#8221;http://www.w3.org/2001/XMLSchema-instance&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:context=&#8221;http://www.springframework.org/schema/context&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:aop=&#8221;http://www.springframework.org/schema/aop&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:tx=&#8221;http://www.springframework.org/schema/tx&#8221;<br />&nbsp;&nbsp;&nbsp; xsi:schemaLocation=&#8221;http://www.springframework.org/schema/beans<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context/spring-context-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd&#8221;&gt; 
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;context:annotation-config /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;context:component-scan base-package=&#8221;com.bluesky&#8221;&nbsp;/&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;sessionFactory&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.LocalSessionFactoryBean&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configLocation&#8221; value=&#8221;classpath:hibernate.cfg.xml&#8221;&nbsp;/&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configurationClass&#8221; value=&#8221;org.hibernate.cfg.AnnotationConfiguration&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;!&#8211; 定义事务管理器（声明式的事务） &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;transactionManager&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.HibernateTransactionManager&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;sessionFactory&#8221; ref=&#8221;sessionFactory&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;tx:advice id=&#8221;txAdvice&#8221; transaction-manager=&#8221;transactionManager&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tx:attributes&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tx:method name=&#8221;*&#8221; propagation=&#8221;REQUIRED&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/tx:attributes&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/tx:advice&gt;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;aop:config&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;aop:pointcut id=&#8221;interceptorPointCuts&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expression=&#8221;execution(* com.bluesky.spring.dao.*.*(..))&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;aop:advisor advice-ref=&#8221;txAdvice&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pointcut-ref=&#8221;interceptorPointCuts&#8221;&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;/aop:config&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&lt;/beans&gt;</p></div>
<p>第五种方式：全注解<br /><!--</p>
<p>Code highlighting produced by Actipro CodeHighlighter (freeware)</p>
<p>http://www.CodeHighlighter.com/</p>
<p>--></p>
<div><!--</p>
<p>Code highlighting produced by Actipro CodeHighlighter (freeware)</p>
<p>http://www.CodeHighlighter.com/</p>
<p>-->&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-8&#8243;?&gt;<br />&lt;beans xmlns=&#8221;http://www.springframework.org/schema/beans&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:xsi=&#8221;http://www.w3.org/2001/XMLSchema-instance&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:context=&#8221;http://www.springframework.org/schema/context&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:aop=&#8221;http://www.springframework.org/schema/aop&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:tx=&#8221;http://www.springframework.org/schema/tx&#8221;<br />&nbsp;&nbsp;&nbsp; xsi:schemaLocation=&#8221;http://www.springframework.org/schema/beans<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/context/spring-context-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd&#8221;&gt; 
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;context:annotation-config /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;context:component-scan base-package=&#8221;com.bluesky&#8221;&nbsp;/&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;tx:annotation-driven transaction-manager=&#8221;transactionManager&#8221;/&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;sessionFactory&#8221;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.LocalSessionFactoryBean&#8221;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configLocation&#8221; value=&#8221;classpath:hibernate.cfg.xml&#8221;&nbsp;/&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;configurationClass&#8221; value=&#8221;org.hibernate.cfg.AnnotationConfiguration&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;!&#8211; 定义事务管理器（声明式的事务） &#8211;&gt;&nbsp;<br />&nbsp;&nbsp;&nbsp; &lt;bean id=&#8221;transactionManager&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class=&#8221;org.springframework.orm.hibernate3.HibernateTransactionManager&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name=&#8221;sessionFactory&#8221; ref=&#8221;sessionFactory&#8221;&nbsp;/&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&nbsp;&nbsp;&nbsp;<br />&lt;/beans&gt;</p></div>
<p>此时在DAO上需加上@Transactional注解，如下：</p>
<div><!--</p>
<p>Code highlighting produced by Actipro CodeHighlighter (freeware)</p>
<p>http://www.CodeHighlighter.com/</p>
<p>-->package com.bluesky.spring.dao; 
<p>&nbsp;</p>
<p>import java.util.List;</p>
<p>import org.hibernate.SessionFactory;<br />import org.springframework.beans.factory.annotation.Autowired;<br />import org.springframework.orm.hibernate3.support.HibernateDaoSupport;<br />import org.springframework.stereotype.Component;</p>
<p>import com.bluesky.spring.domain.User;</p>
<p>@Transactional<br />@Component(&#8220;userDao&#8221;)<br />public&nbsp;class UserDaoImpl extends HibernateDaoSupport implements UserDao {</p>
<p>&nbsp;&nbsp;&nbsp; public List&lt;User&gt; listUsers() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;this.getSession().createQuery(&#8220;from User&#8221;).list();<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; <img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />}</p></div><!-- .entry-content --><img src ="http://www.blogjava.net/tjyhy590/aggbug/362191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-10-27 19:29 <a href="http://www.blogjava.net/tjyhy590/archive/2011/10/27/362191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>集群和分布式 </title><link>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362190.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Thu, 27 Oct 2011 11:28:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362190.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/362190.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/362190.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/362190.html</trackback:ping><description><![CDATA[<div class="blog_content" id="blog_content">
<h2>集群概念</h2>
<p><strong>1. 两大关键特性 <br /></strong>集群是一组协同工作的服务实体，用以提供比单一服务实体更具扩展性与可用性的服务平台。在客户端看来，一个集群就象是一个服务实体，但事实上集群由一组服务实体组成。与单一服务实体相比较，集群提供了以下两个关键特性：</p>
<p>&#183;&nbsp; 可扩展性－－集群的性能不限于单一的服务实体，新的服务实体可以动态地加入到集群，从而增强集群的性能。</p>
<p>&#183;&nbsp; 高可用性－－集群通过服务实体冗余使客户端免于轻易遇到out of service的警告。在集群中，同样的服务可以由多个服务实体提供。如果一个服务实体失败了，另一个服务实体会接管失败的服务实体。集群提供的从一个出错的服务实体恢复到另一个服务实体的功能增强了应用的可用性。</p>
<p><strong>2. 两大能力 </strong><br />为了具有可扩展性和高可用性特点，集群的必须具备以下两大能力：</p>
<p>&#183;&nbsp; 负载均衡－－负载均衡能把任务比较均衡地分布到集群环境下的计算和网络资源。</p>
<p>&#183;&nbsp; 错误恢复－－由于某种原因，执行某个任务的资源出现故障，另一服务实体中执行同一任务的资源接着完成任务。这种由于一个实体中的资源不能工作，另一个实体中的资源透明的继续完成任务的过程叫错误恢复。</p>
<p>负载均衡和错误恢复都要求各服务实体中有执行同一任务的资源存在，而且对于同一任务的各个资源来说，执行任务所需的信息视图（信息上下文）必须是一样的。</p>
<p><strong>3. 两大技术</strong> <br />实现集群务必要有以下两大技术：</p>
<p>&#183;&nbsp; 集群地址－－集群由多个服务实体组成，集群客户端通过访问集群的集群地址获取集群内部各服务实体的功能。具有单一集群地址（也叫单一影像）是集群的一个基本特征。维护集群地址的设置被称为负载均衡器。负载均衡器内部负责管理各个服务实体的加入和退出，外部负责集群地址向内部服务实体地址的转换。有的负载均衡器实现真正的负载均衡算法，有的只支持任务的转换。只实现任务转换的负载均衡器适用于支持ACTIVE-STANDBY的集群环境，在那里，集群中只有一个服务实体工作，当正在工作的服务实体发生故障时，负载均衡器把后来的任务转向另外一个服务实体。</p>
<p>&#183;&nbsp; 内部通信－－为了能协同工作、实现负载均衡和错误恢复，集群各实体间必须时常通信，比如负载均衡器对服务实体心跳测试信息、服务实体间任务执行上下文信息的通信。</p>
<p>具有同一个集群地址使得客户端能访问集群提供的计算服务，一个集群地址下隐藏了各个服务实体的内部地址，使得客户要求的计算服务能在各个服务实体之间分布。内部通信是集群能正常运转的基础，它使得集群具有均衡负载和错误恢复的能力。</p>
<h2>集群分类</h2>
<p>Linux集群主要分成三大类( 高可用集群， 负载均衡集群，科学计算集群)</p>
<p>高可用集群( High Availability Cluster)<br />负载均衡集群(Load Balance Cluster)<br />科学计算集群(High Performance Computing Cluster)<br />================================================</p>
<p>具体包括：</p>
<p>Linux High Availability 高可用集群&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />(普通两节点双机热备，多节点HA集群，RAC, shared, share-nothing集群等)</p>
<p>Linux Load Balance 负载均衡集群&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;(LVS等....)</p>
<p>Linux High Performance Computing 高性能科学计算集群&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;(Beowulf 类集群....)</p>
<p>分布式存储&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />其他类linux集群&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />(如Openmosix, rendering farm 等..)</p>
<h2>详细介绍</h2>
<p><strong>1. 高可用集群(High Availability Cluster)<br /></strong>常见的就是2个节点做成的HA集群，有很多通俗的不科学的名称，比如"双机热备", "双机互备", "双机".<br />高可用集群解决的是保障用户的应用程序持续对外提供服务的能力。 (请注意高可用集群既不是用来保护业务数据的，保护的是用户的业务程序对外不间断提供服务，把因软件/硬件/人为造成的故障对业务的影响降低到最小程度)。</p>
<p><strong>2. 负载均衡集群(Load Balance Cluster)</strong></p>
<p>负载均衡系统：集群中所有的节点都处于活动状态，它们分摊系统的工作负载。一般Web服务器集群、数据库集群和应用服务器集群都属于这种类型。</p>
<p>负载均衡集群一般用于相应网络请求的网页服务器，数据库服务器。这种集群可以在接到请求时，检查接受请求较少，不繁忙的服务器，并把请求转到这些服务器上。从检查其他服务器状态这一点上看，负载均衡和容错集群很接近，不同之处是数量上更多。</p>
<p><strong>3. 科学计算集群(High Performance Computing Cluster)</strong></p>
<p>高性能计算(High Perfermance Computing)集群，简称HPC集群。这类集群致力于提供单个计算机所不能提供的强大的计算能力。</p>
<p>高性能计算分类　　<br />　高吞吐计算(High-throughput Computing)<br />　　有一类高性能计算，可以把它分成若干可以并行的子任务，而且各个子任务彼此间没有什么关联。象在家搜寻外星人（ <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#83;&#69;&#84;&#73;&#64;&#72;&#79;&#77;&#69;"><font color="#108ac6">SETI@HOME</font></a> -- Search for Extraterrestrial Intelligence at Home ）就是这一类型应用。这一项目是利用Internet上的闲置的计算资源来搜寻外星人。SETI项目的服务器将一组数据和数据模式发给Internet上参加SETI的计算节点，计算节点在给定的数据上用给定的模式进行搜索，然后将搜索的结果发给服务器。服务器负责将从各个计算节点返回的数据汇集成完整的数据。因为这种类型应用的一个共同特征是在海量数据上搜索某些模式，所以把这类计算称为高吞吐计算。所谓的Internet计算都属于这一类。按照Flynn的分类，高吞吐计算属于SIMD（Single Instruction/Multiple Data）的范畴。</p>
<p>&nbsp;分布计算(Distributed Computing)<br />　　另一类计算刚好和高吞吐计算相反，它们虽然可以给分成若干并行的子任务，但是子任务间联系很紧密，需要大量的数据交换。按照Flynn的分类，分布式的高性能计算属于MIMD（Multiple Instruction/Multiple Data）的范畴。</p>
<p><strong>4. 分布式（集群）与集群的联系与区别 <br /></strong>分布式是指将不同的业务分布在不同的地方。 <br />而集群指的是将几台服务器集中在一起，实现同一业务。 <br />分布式中的每一个节点，都可以做集群。 <br />而集群并不一定就是分布式的。 <br />举例：就比如新浪网，访问的人多了，他可以做一个群集，前面放一个响应服务器，后面几台服务器完成同一业务，如果有业务访问的时候，响应服务器看哪台服务器的负载不是很重，就将给哪一台去完成。 <br />而分布式，从窄意上理解，也跟集群差不多， 但是它的组织比较松散，不像集群，有一个组织性，一台服务器垮了，其它的服务器可以顶上来。 <br />分布式的每一个节点，都完成不同的业务，一个节点垮了，哪这个业务就不可访问了。</p></div><script type="text/javascript"><!--
google_ad_client = "pub-1076724771190722";
/* JE个人博客468x60 */
google_ad_slot = "5506163105";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
</script><script src="http://pagead2.googlesyndication.com/pagead/js/r20111019/r20110914/show_ads_impl.js"></script><script src="http://pagead2.googlesyndication.com/pagead/render_ads.js"></script><script>google_protectAndRun("render_ads.js::google_render_ad", google_handleError, google_render_ad);</script><img src ="http://www.blogjava.net/tjyhy590/aggbug/362190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-10-27 19:28 <a href="http://www.blogjava.net/tjyhy590/archive/2011/10/27/362190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件设计的七大原则 </title><link>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362189.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Thu, 27 Oct 2011 11:27:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362189.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/362189.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/10/27/362189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/362189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/362189.html</trackback:ping><description><![CDATA[<p>设计模式遵循的一般原则：</p>
<p>1.<strong>开-闭原则(Open-Closed Principle, OCP):</strong>一个软件实体应当对扩展开发,对修改关闭.说的是,再设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展.换言之,应当可以在不必修改源代码的情况下改变这个模块的行为，在保持系统一定稳定性的基础上，对系统进行扩展。这是面向对象设计（OOD）的基石，也是最重要的原则。</p>
<p>2.<strong>里氏代换原则(Liskov Substitution Principle,常缩写为.LSP</strong>)<br />(1).由Barbar Liskov(芭芭拉.里氏)提出，是继承复用的基石。<br />(2).严格表达:如果每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都代换称o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型.<br />&nbsp;&nbsp;&nbsp; 换言之,一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别.只有衍生类可以替换基类，软件单位的功能才能不受影响，基类才能真正被复用，而衍生类也能够在基类的基础上增加新功能。<br />(3).反过来的代换不成立<br />(4).&lt;墨子.小取&gt;中说:"白马,马也; 乘白马,乘马也.骊马(黑马),马也;乘骊马,乘马也."<br />(5).该类西方著名的例程为:正方形是否是长方形的子类(答案是"否")。类似的还有椭圆和圆的关系。<br />(6).应当尽量从抽象类继承,而不从具体类继承,一般而言,如果有两个具体类A,B有继承关系,那么一个最简单的修改方案是建立一个抽象类C,然后让类A和B成为抽象类C的子类.即如果有一个由继承关系形成的登记结构的话,那么在等级结构的树形图上面所有的树叶节点都应当是具体类;而所有的树枝节点都应当是抽象类或者接口.<br />(7)."基于契约设计(Design By Constract),简称DBC"这项技术对LISKOV代换原则提供了支持.该项技术Bertrand Meyer伯特兰做过详细的介绍:<br />使用DBC,类的编写者显式地规定针对该类的契约.客户代码的编写者可以通过该契约获悉可以依赖的行为方式.契约是通过每个方法声明的前置条件(preconditions)和后置条件(postconditions)来指定的.要使一个方法得以执行,前置条件必须为真.执行完毕后,该方法要保证后置条件为真.就是说,在重新声明派生类中的例程(routine)时,只能使用相等或者更弱的前置条件来替换原始的前置条件,只能使用相等或者更强的后置条件来替换原始的后置条件.</p>
<p>3.<strong>依赖倒置原则(Dependence Inversion Principle),</strong>要求客户端依赖于抽象耦合.<br />(1)表述:抽象不应当依赖于细节,细节应当依赖于抽象.(Program to an interface, not an implementaction)<br />(2)表述二:针对接口编程的意思是说,应当使用接口和抽象类进行变量的类型声明,参量的类型声明,方法的返还类型声明,以及数据类型的转换等.不要针对实现编程的意思就是说,不应当使用具体类进行变量的类型声明,参量类型声明,方法的返还类型声明,以及数据类型的转换等.<br />&nbsp;&nbsp; 要保证做到这一点,一个具体的类应等只实现接口和抽象类中声明过的方法,而不应当给出多余的方法.<br />&nbsp;&nbsp; 只要一个被引用的对象存在抽象类型,就应当在任何引用此对象的地方使用抽象类型,包括参量的类型声明,方法返还类型的声明,属性变量的类型声明等.<br />(3)接口与抽象的区别就在于抽象类可以提供某些方法的部分实现,而接口则不可以,这也大概是抽象类唯一的优点.如果向一个抽象类加入一个新的具体方法,那么所有的子类型一下子就都得到得到了这个新的具体方法,而接口做不到这一点.如果向一个接口加入了一个新的方法的话,所有实现这个接口的类就全部不能通过编译了,因为它们都没有实现这个新声明的方法.这显然是接口的一个缺点.<br />(4)一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的登记结构中,而由于一般语言都限制一个类只能从最多一个超类继承,因此将抽象作为类型定义工具的效能大打折扣.<br />&nbsp;&nbsp; 反过来,看接口,就会发现任何一个实现了一个接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个接口.<br />(5)从代码重构的角度上讲,将一个单独的具体类重构成一个接口的实现是很容易的,只需要声明一个接口,并将重要的方法添加到接口声明中,然后在具体类定义语句中加上保留字以继承于该接口就行了.<br />&nbsp;&nbsp; 而作为一个已有的具体类添加一个抽象类作为抽象类型不那么容易,因为这个具体类有可能已经有一个超类.这样一来,这个新定义的抽象类只好继续向上移动,变成这个超类的超类,如此循环,最后这个新的抽象类必定处于整个类型等级结构的最上端,从而使登记结构中的所有成员都会受到影响.<br />(6)接口是定义混合类型的理想工具,所为混合类型,就是在一个类的主类型之外的次要类型.一个混合类型表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为.<br />(7)联合使用接口和抽象类:<br />&nbsp;&nbsp; 由于抽象类具有提供缺省实现的优点,而接口具有其他所有优点,所以联合使用两者就是一个很好的选择.<br />&nbsp;&nbsp; 首先,声明类型的工作仍然接口承担的,但是同时给出的还有一个抽象类,为这个接口给出一个缺省实现.其他同属于这个抽象类型的具体类可以选择实现这个接口,也可以选择继承自这个抽象类.如果一个具体类直接实现这个接口的话,它就必须自行实现所有的接口;相反,如果它继承自抽象类的话,它可以省去一些不必要的的方法,因为它可以从抽象类中自动得到这些方法的缺省实现;如果需要向接口加入一个新的方法的话,那么只要同时向这个抽象类加入这个方法的一个具体实现就可以了,因为所有继承自这个抽象类的子类都会从这个抽象类得到这个具体方法.这其实就是缺省适配器模式(Defaule Adapter).<br />(8)什么是高层策略呢?它是应用背后的抽象,是那些不随具体细节的改变而改变的真理. 它是系统内部的系统____隐喻.</p>
<p>4.<strong>接口隔离原则(Interface Segregation Principle, ISP)<br /></strong>（1）一个类对另外一个类的依赖是建立在最小的接口上。</p>
<p>（2）使用多个专门的接口比使用单一的总接口要好.根据客户需要的不同,而为不同的客户端提供不同的服务是一种应当得到鼓励的做法.就像"看人下菜碟"一样,要看客人是谁,再提供不同档次的饭菜.<br />（3）胖接口会导致他们的客户程序之间产生不正常的并且有害的耦合关系.当一个客户程序要求该胖接口进行一个改动时,会影响到所有其他的客户程序.因此客户程序应该仅仅依赖他们实际需要调用的方法.<br />&nbsp;&nbsp;&nbsp;&nbsp; <br />5.<strong>合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)<br /></strong>在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过这些向对象的委派达到复用已有功能的目的.这个设计原则有另一个简短的表述:要尽量使用合成/聚合,尽量不要使用继承.</p>
<p>6.<strong>迪米特法则(Law of Demeter LoD)又叫做最少知识原则(Least Knowledge Principle,LKP),</strong>就是说,一个对象应当对其他对象有尽可能少的了了解.<br />迪米特法则最初是用来作为面向对象的系统设计风格的一种法则,与1987年秋天由Ian Holland在美国东北大学为一个叫做迪米特(Demeter)的项目设计提出的,因此叫做迪米特法则[LIEB89][LIEB86].这条法则实际上是很多著名系统,比如火星登陆软件系统,木星的欧罗巴卫星轨道飞船的软件系统的指导设计原则.<br />没有任何一个其他的OO设计原则象迪米特法则这样有如此之多的表述方式,如下几种:<br />(1)只与你直接的朋友们通信(Only talk to your immediate friends)<br />(2)不要跟"陌生人"说话(Don't talk to strangers)<br />(3)每一个软件单位对其他的单位都只有最少的知识,而且局限于那些本单位密切相关的软件单位.<br />就是说,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。</p>
<p>7.<strong>单一职责原则(Simple responsibility pinciple SRP)<br /></strong>就一个类而言,应该仅有一个引起它变化的原因,如果你能想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.应该把多于的指责分离出去,分别再创建一些类来完成每一个职责.<br /><br /><span style="color: red">另外：常说的OO五大原则就是指其中的 ：1、单一职责原则；2、开放闭合原则；3、里氏替换原则；4、依赖倒置原则；5、接口隔离原则。</span></p><img src ="http://www.blogjava.net/tjyhy590/aggbug/362189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-10-27 19:27 <a href="http://www.blogjava.net/tjyhy590/archive/2011/10/27/362189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JS技巧代码实例</title><link>http://www.blogjava.net/tjyhy590/archive/2011/09/08/358277.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Thu, 08 Sep 2011 03:02:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/09/08/358277.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/358277.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/09/08/358277.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/358277.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/358277.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1.文本框焦点问题onBlur:当失去输入焦点后产生该事件onFocus:当输入获得焦点后，产生该文件Onchange:当文字值改变时，产生该事件Onselect:当文字加亮后，产生该文件&lt;input type="text" value="mm" onfocus="if(value=='mm) {value=''}" onblur="if(value=='') {value='mm'}"&g...&nbsp;&nbsp;<a href='http://www.blogjava.net/tjyhy590/archive/2011/09/08/358277.html'>阅读全文</a><img src ="http://www.blogjava.net/tjyhy590/aggbug/358277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-09-08 11:02 <a href="http://www.blogjava.net/tjyhy590/archive/2011/09/08/358277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用memcached实现session远程分布式存储</title><link>http://www.blogjava.net/tjyhy590/archive/2011/03/29/347223.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Tue, 29 Mar 2011 09:21:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/03/29/347223.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/347223.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/03/29/347223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/347223.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/347223.html</trackback:ping><description><![CDATA[<p>为了使web应用能使用saas模式的大规模访问,必须实现应用的集群部署.要实现集群部署主要需要实现session共享机制,使得多台应用服务器之间会话统一, tomcat等多数服务都采用了session复制技术实现session的共享.</p>
<p>&nbsp;&nbsp; session复制技术的问题:</p>
<p>&nbsp;&nbsp; (1)技术复杂,必须在同一种中间件之间完成(如:tomcat-tomcat之间).</p>
<p>&nbsp;&nbsp; (2)在节点持续增多的情况下,session复制带来的性能损失会快速增加.特别是当session中保存了较大的对象,而且对象变化较快时,性能下降更加显著.这种特性使得web应用的水平扩展受到了限制.</p>
<p>&nbsp;&nbsp; session共享的另一种思路就是把session集中起来管理,首先想到的是采用数据库来集中存储session,但数据库是文件存储相对内存慢了一个数量级,同时这势必加大数据库系统的负担.所以需要一种既速度快又能远程集中存储的服务,所以就想到了memcached.</p>
<p>&nbsp;&nbsp; </p>
<p>memcached是什么?</p>
<p>&nbsp; memcached是由Danga Interactive开发的，高性能的，分布式的内存对象缓存系统，用于在动态应用中减少数据库负载，提升访问速度。</p>
<p>memcached能缓存什么？</p>
<p>&nbsp; 通过在内存里维护一个统一的巨大的hash表，Memcached能够用来存储各种格式的数据，包括图像、视频、文件以及数据库检索的结果等。</p>
<p>memcached快么？</p>
<p>&nbsp; 非常快。memcached使用了libevent（如果可以的话，在linux下使用epoll）来均衡任何数量的打开链接，使用非阻塞的网络I/O，对内部对象实现引用计数(因此，针对多样的客户端，对象可以处在多样的状态)， 使用自己的页块分配器和哈希表， 因此虚拟内存不会产生碎片并且虚拟内存分配的时间复杂度可以保证为O(1).。</p>
<p>Danga Interactive为提升Danga Interactive的速度研发了memcached。目前，LiveJournal.com每天已经在向一百万用户提供多达两千万次的页面访问。而这些，是由一个由web服务器和数据库服务器组成的集群完成的。memcached几乎完全放弃了任何数据都从数据库读取的方式，同时，它还缩短了用户查看页面的速度、更好的资源分配方式，以及memcache失效时对数据库的访问速度。</p>
<p>memcached的特点</p>
<p>&nbsp; memcached的缓存是一种分布式的，可以让不同主机上的多个用户同时访问， 因此解决了共享内存只能单机应用的局限，更不会出现使用数据库做类似事情的时候，磁盘开销和阻塞的发生。</p>
<p>&nbsp; 使用memcached来存储session有两种方案:</p>
<p>(1)直接通过tomcat6的扩展机制实现.</p>
<p>&nbsp; 参考: http://www.javaeye.com/topic/81641</p>
<p>(2)通过自己编写filter实现.</p>
<p>考虑到系统的扩展,我们采用这种方案.这样可以使session共享机制和中间件脱钩.</p>
<p>&nbsp;参考: http://www.javaeye.com/topic/82565</p>
<p>主要思路:</p>
<p>(1)继承重构HttpServletRequestWrapper,HttpSessionWrapper类,覆盖原来和session存取相关的方法呢,都通过SessionService类来实现.</p>
<p>(2)使用filter拦截cookie中的sessionId,通过sessionId构造新的HttpServletRequestWrapper对象,传给后面的应用.</p>
<p>(3)SessionService连接memcached服务,以sessionId作为key,存取的对象是一个map.map的内容即为session的内容.</p>
<p>使用过程注意几个问题和改进思路： <br />
1、memcache的内存应该足够大，这样不会出现用户session从Cache中被清除的问题(可以关闭memcached的对象退出机制)。 <br />
2、如果session的读取比写入要多很多，可以在memcache前再加一个Oscache等本地缓存，减少对memcache的读操作，从而减小网络开销，提高性能。 <br />
3、如果用户非常多，可以使用memcached组，通过set方法中带hashCode，插入到某个memcached服务器 </p>
<p>对于session的清除有几种方案:</p>
<p>(1)可以在凌晨人最少的时候，对memcached做一次清空。(简单)</p>
<p>(2)保存在缓存中的对象设置一个失效时间,通过过滤器获取sessionId的值,定期刷新memcached中的对象.长时间没有被刷新的对象自动被清除.(相对复杂,消耗资源)</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/tjyhy590/aggbug/347223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-03-29 17:21 <a href="http://www.blogjava.net/tjyhy590/archive/2011/03/29/347223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Drawable、Bitmap、byte[]之间的转换 (android转)</title><link>http://www.blogjava.net/tjyhy590/archive/2011/02/17/344512.html</link><dc:creator>鸿雁</dc:creator><author>鸿雁</author><pubDate>Thu, 17 Feb 2011 01:35:00 GMT</pubDate><guid>http://www.blogjava.net/tjyhy590/archive/2011/02/17/344512.html</guid><wfw:comment>http://www.blogjava.net/tjyhy590/comments/344512.html</wfw:comment><comments>http://www.blogjava.net/tjyhy590/archive/2011/02/17/344512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tjyhy590/comments/commentRss/344512.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tjyhy590/services/trackbacks/344512.html</trackback:ping><description><![CDATA[android在处理一写图片资源的时候，会进行一些类型的转换，现在有空整理一下： <br />
<br />
1、Drawable &#8594; Bitmap 的简单方法 <br />
((BitmapDrawable)res.getDrawable(R.drawable.youricon)).getBitmap(); <br />
<br />
<br />
2、Drawable &#8594; Bitmap <br />
Java代码 <br />
public static Bitmap drawableToBitmap(Drawable drawable) {&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Bitmap bitmap = Bitmap&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;.createBitmap(&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; drawable.getIntrinsicWidth(),&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; drawable.getIntrinsicHeight(),&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;: Bitmap.Config.RGB_565);&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Canvas canvas = new Canvas(bitmap);&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//canvas.setBitmap(bitmap);&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;drawable.draw(canvas);&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return bitmap;&nbsp;&nbsp;<br />
}&nbsp;&nbsp;<br />
<br />
<br />
3.Bitmap&#8594;Drawable&nbsp; &nbsp;的简单方法 <br />
BitmapDrawable bitmapDrawable = (BitmapDrawable)bitmap;&nbsp; &nbsp;&nbsp;&nbsp;<br />
Drawable drawable = (Drawable)bitmapDrawable;&nbsp; &nbsp;&nbsp;&nbsp;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
Bitmap bitmap = new Bitmap (...);&nbsp; &nbsp;&nbsp;&nbsp;<br />
Drawable drawable = new BitmapDrawable(bitmap);&nbsp; &nbsp;<br />
<br />
<br />
3、从资源中获取Bitmap <br />
Java代码 <br />
Resources res=getResources();&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic);&nbsp;&nbsp;<br />
<br />
<br />
<br />
<br />
<br />
4、Bitmap &#8594; byte[] <br />
Java代码 <br />
private byte[] Bitmap2Bytes(Bitmap bm){&nbsp;&nbsp;<br />
&nbsp; &nbsp; ByteArrayOutputStream baos = new ByteArrayOutputStream();&amp;nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp; bm.compress(Bitmap.CompressFormat.PNG, 100, baos);&amp;nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp; return baos.toByteArray();&nbsp;&nbsp;<br />
}&nbsp;&nbsp;<br />
<br />
<br />
5、 byte[] &#8594; Bitmap <br />
Java代码 <br />
private Bitmap Bytes2Bimap(byte[] b){&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if(b.length!=0){&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; return BitmapFactory.decodeByteArray(b, 0, b.length);&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;else {&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; return null;&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}&nbsp;&nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;} <br />
<img src ="http://www.blogjava.net/tjyhy590/aggbug/344512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tjyhy590/" target="_blank">鸿雁</a> 2011-02-17 09:35 <a href="http://www.blogjava.net/tjyhy590/archive/2011/02/17/344512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>