本文内容

  • 背景
  • ES集群中第一个master节点
  • ES slave节点

迁移到:http://www.bdata-cap.com/newsinfo/1712679.html

本文总结 Elasticsearch(以下简称ES)搭建集群的经验。以 Elasticsearch-rtf-2.2.1 版本为例。

我搭过三个集群:研究ELK时搭了一个;测试环境搭了一个;生产环境搭了一个。回想起来,搭建这三个集群时遇到的问题都不一样(我这么说,主要针对集群中节点发现,以及master问题,而不是es启动不起来或报错等问题)~

  • 研究ELK时,搭建ES集群倒是很顺利,原因很简单,先从一台机器开始的;
  • 可是测试环境搭建集群时,遭遇新加入节点一直不能发现 master 节点,或是集群节点出现都选举自己为 master 这两个情况,因为,节点都是陆续启动的,配置不当,是会出问题;
  • 等到在生产环境搭建集群时,遭遇无法选举出 master 节点的情况。ES head 和 kopf 两个插件都不可用,因为,既然集群没有选举出 master 节点,显然,整个集群是用不了的。而前面的情况,head 和 kopf 插件还是能用的,但能用,意义也不大~

总结起来,搭建集群,应该注意两个问题。首先,当然是 Elasticsearch.yml 配置是否正确;再就是你的操作方式。比如节点启动步骤等。

因为,如果搭建一个集群,那么必须保证集群有一个 master 节点,一般来说,第一个启动的节点,一定是 master。然后,分别启动其他节点,这些节点就会找到 master 节点,而 master 节点,也会发现这些节点。

  • 因此,配置集群中的第一个master节点,务必简单(简单到什么程度,后面再说),先启动它,它会立刻成为 master 节点。之后,再配置其他节点,最好直接告诉它们,可能的 master 节点是什么,然后启动他们,它们就会发现 master,而 master 节点,也会发现新加入的节点。
  • 否则,如果第一个启动的节点,配置过于复杂(条件苛刻),造成它不能成为 master 节点,那么,整个集群会失败。

稍后,你再配置节点时,可以采用更高级、复杂点的配置,就不会有什么问题了~

所以,我才强调,ES 集群中第一个 master 节点的配置务必简单,以后再调整。

背景


假设,我们想搭建这样一个名为 myfirstcluster 的ES集群,它有两个节点:

节点 主机名 是否为 master
192.168.1.2 es-01
192.168.1.3 es-02

ES集群中第一个master节点


最简单的 ES master 节点配置如下。该配置文件,是一个完整的 ES 配置文件,所以很长。我顺便翻译成了中文。

   1: # ======================== Elasticsearch Configuration =========================

   2: #

   3: # 注意: Elasticsearch 大多数设置都有默认值.

   4: #       在你着手调整和优化配置之前,确保你明白你期望什么,得到什么结果

   5: #

   6: # 配置一个节点的主要方式就是通过该文件. 该模板列出了大多数重要的设置.

   7: #

   8: # 更多配置选项参见如下链接:

   9: # <http://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html>

  10: #

  11: # ---------------------------------- 集群 -----------------------------------

  12: #

  13: # 集群名称:

  14: #

  15: cluster.name: mycluster

  16: #

  17: # ------------------------------------ 节点 ------------------------------------

  18: #

  19: # 节点名称:

  20: #

  21: node.name: es-01

  22: node.master: true

  23: node.data: true

  24: #

  25: # 为节点添加自定义属性,如机架:

  26: #

  27: # node.rack: r1

  28: #

  29: # ----------------------------------- 路径 ------------------------------------

  30: #

  31: # 存放数据的目录 (多个目录用逗号分隔):

  32: #

  33: # path.data: /path/to/data

  34: #

  35: # 日志文件目录:

  36: #

  37: # path.logs: /path/to/logs

  38: #

  39: # ----------------------------------- 内存 -----------------------------------

  40: #

  41: # 启动时锁定内存:

  42: #

  43: # bootstrap.mlockall: true

  44: #

  45: # 确保设置了 `ES_HEAP_SIZE` 环境变量, 大小为系统内存的一半,

  46: # 该值为线程可以使用的最大内存

  47: #

  48: # 当系统正在交换内存时, Elasticsearch 执行性能会很差.

  49: #

  50: # ---------------------------------- 网络 -----------------------------------

  51: #

  52: # 设置绑定地址到指定IP (IPv4 or IPv6):

  53: #

  54: network.host: 192.168.1.2

  55: #

  56: # 设置自定义 HTTP 端口:

  57: http.port: 9200

  58: # 集群内部通信端口:

  59: tcp.port: 9300

  60: #

  61: # 更多信息, 参见如下链接:

  62: # <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html>

  63: #

  64: # --------------------------------- 节点发现 ----------------------------------

  65: #

  66: # 当新节点加入时,传递一个主机的初始化列表以完成节点发现:

  67: # 默认主机列表为 ["127.0.0.1", "[::1]"]

  68: #

  69: discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300"]

  70: #

  71: # 通过配置大多数节点阻止脑裂现象 (数量: 节点总数量 / 2 + 1):

  72: #

  73: # discovery.zen.minimum_master_nodes: 2

  74: #

  75: # 更多信息, 参见如下链接:

  76: # <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery.html>

  77: #

  78: # ---------------------------------- 网关 -----------------------------------

  79: #

  80: # 当整个集群重新启动后, 只有 N 个节点启动了, 集群才会恢复,否则将阻塞:

  81: #

  82: # gateway.recover_after_nodes: 2

  83: #

  84: # 更多信息, 参见如下链接:

  85: # <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-gateway.html>

  86: #

  87: # ---------------------------------- 其他 -----------------------------------

  88: #

  89: # 禁止在一个系统上启动多个节点:

  90: #

  91: # node.max_local_storage_nodes: 1

  92: #

  93: # 当删除 index 是必需显式名称:

  94: #

  95: # action.destructive_requires_name: true

  96:  

  97: index:

  98:   analysis:

  99:     tokenizer:

 100:       my_pinyin:

 101:         type: pinyin

 102:         first_letter: prefix

 103:         padding_char: ''

 104:       pinyin_first_letter:

 105:         type: pinyin

 106:         first_letter: only

 107:       mmseg_maxword:

 108:         type: mmseg

 109:         seg_type: max_word

 110:       mmseg_complex:

 111:         type: mmseg

 112:         seg_type: complex

 113:       mmseg_simple:

 114:         type: mmseg

 115:         seg_type: simple

 116:       semicolon_spliter:

 117:         type: pattern

 118:         pattern: ";"

 119:       pct_spliter:

 120:         type: pattern

 121:         pattern: "[%]+"

 122:       ngram_1_to_2:

 123:         type: nGram

 124:         min_gram: 1

 125:         max_gram: 2

 126:       ngram_1_to_3:

 127:         type: nGram

 128:         min_gram: 1

 129:         max_gram: 3

 130:     filter:

 131:       ngram_min_3:

 132:         max_gram: 10

 133:         min_gram: 3

 134:         type: nGram

 135:       ngram_min_2:

 136:         max_gram: 10

 137:         min_gram: 2

 138:         type: nGram

 139:       ngram_min_1:

 140:         max_gram: 10

 141:         min_gram: 1

 142:         type: nGram

 143:       min2_length:

 144:         min: 2

 145:         max: 4

 146:         type: length

 147:       min3_length:

 148:         min: 3

 149:         max: 4

 150:         type: length

 151:       pinyin_first_letter:

 152:         type: pinyin

 153:         first_letter: only

 154:     analyzer:

 155:       lowercase_keyword:

 156:         type: custom

 157:         filter:

 158:         - lowercase

 159:         tokenizer: standard

 160:       lowercase_keyword_ngram_min_size1:

 161:         type: custom 

 162:         filter:

 163:         - lowercase 

 164:         - stop

 165:         - trim

 166:         - unique

 167:         tokenizer: nGram

 168:       lowercase_keyword_ngram_min_size2:

 169:         type: custom

 170:         filter:

 171:         - lowercase

 172:         - min2_length

 173:         - stop

 174:         - trim

 175:         - unique

 176:         tokenizer: nGram

 177:       lowercase_keyword_ngram_min_size3:

 178:         type: custom

 179:         filter:

 180:         - lowercase

 181:         - min3_length

 182:         - stop

 183:         - trim

 184:         - unique

 185:         tokenizer: ngram_1_to_3 

 186:       lowercase_keyword_ngram:

 187:         type: custom

 188:         filter:

 189:         - lowercase

 190:         - stop

 191:         - trim

 192:         - unique

 193:         tokenizer: ngram_1_to_3

 194:       lowercase_keyword_without_standard:

 195:         type: custom

 196:         filter:

 197:         - lowercase

 198:         tokenizer: keyword

 199:       lowercase_whitespace:

 200:         type: custom

 201:         filter:

 202:         - lowercase

 203:         tokenizer: whitespace

 204:       ik:

 205:         alias:

 206:         - ik_analyzer

 207:         type: ik

 208:       ik_max_word:

 209:         type: ik

 210:         use_smart: true

 211:       ik_smart:

 212:         type: ik

 213:         use_smart: true

 214:       mmseg:

 215:         alias:

 216:         - mmseg_analyzer

 217:         type: mmseg

 218:       mmseg_maxword:

 219:         type: custom

 220:         filter:

 221:         - lowercase

 222:         tokenizer: mmseg_maxword

 223:       mmseg_complex:

 224:         type: custom

 225:         filter:

 226:         - lowercase

 227:         tokenizer: mmseg_complex

 228:       mmseg_simple:

 229:         type: custom

 230:         filter:

 231:         - lowercase

 232:         tokenizer: mmseg_simple

 233:       comma_spliter:

 234:         type: pattern

 235:         pattern: "[,|\\s]+"

 236:       pct_spliter:

 237:         type: pattern

 238:         pattern: "[%]+"

 239:       custom_snowball_analyzer:

 240:         type: snowball

 241:         language: English

 242:       simple_english_analyzer:

 243:         type: custom

 244:         tokenizer: whitespace

 245:         filter:

 246:         - standard

 247:         - lowercase

 248:         - snowball

 249:       edge_ngram:

 250:         type: custom

 251:         tokenizer: edgeNGram

 252:         filter:

 253:         - lowercase

 254:       pinyin_ngram_analyzer:

 255:         type: custom

 256:         tokenizer: my_pinyin

 257:         filter:

 258:         - lowercase

 259:         - nGram

 260:         - trim

 261:         - unique

 262:       pinyin_first_letter_analyzer:

 263:         type: custom

 264:         tokenizer: pinyin_first_letter

 265:         filter:

 266:         - standard

 267:         - lowercase

 268:       pinyin_first_letter_keyword_analyzer:

 269:         alias:

 270:         - pinyin_first_letter_analyzer_keyword

 271:         type: custom

 272:         tokenizer: keyword

 273:         filter:

 274:         - pinyin_first_letter

 275:         - lowercase

 276:       path_analyzer: #used for tokenize :/something/something/else

 277:         type: custom

 278:         tokenizer: path_hierarchy 

 279:  

 280: #index.analysis.analyzer.default.type: mmseg

 281: index.analysis.analyzer.default.type: ik 

 282:  

 283: # rtf.filter.redis.host: 127.0.0.1

 284: # rtf.filter.redis.port: 6379

说明:

  • 第15行,指定集群名称 myfirstcluster;
  • 第21行,指定节点名称,最好写主机名;
  • 第22和23行,指定该是否可能为master节点,以及是否为数据节点。ES的所说master节点,其实弱化了很多,仅仅就是为了节点发现和选举master节点而已,它甚至都可以不用来保存数据。

因此,看你的规划,完全可以让一个 master 节点,不保存任何数据;

  • 第54行,指定节点IP地址,192.168.1.2;
  • 第57行,指定HTTP端口,比如,head、kopf插件等插件,都使用该端口。事实上,你可以指定从 92开头的任何端口;
  • 第59行,指定集群内部通信的端口,比如,节点发现都使用该端口。事实上,你可以指定93开头的任何端口,该行也可以写成“transport.tcp.port: 9300”;

这7行配置,在我看来,针对集群中第一个master节点,必须配置正确的。其他配置,可以暂时不用。

其中,第57行和第59行,实际上,一台物理机,是可以运行多个 ES,只需要指定不同的配置文件即可。

  • 第69行,指定节点初始化列表,因为该节点是集群第一台机器,并且要当 master,所以写”127.0.0.1:9300”,端口号,就是你在第59行指定的端口。相关资料显示,也可以不指定端口,那是不是会93开头的所有端口扫描一下呢?;
  • 从97行开始,是配置ES的分词。

slave 节点


Slave 节点配置如下。该配置文件内容只列出了配置项,但是是完整的。

   1: # ======================== Elasticsearch Configuration =========================

   2: #

   3: # ---------------------------------- Cluster -----------------------------------

   4: #

   5: # Use a descriptive name for your cluster:

   6: #

   7: cluster.name: myfirstcluster

   8: #

   9: # ------------------------------------ Node ------------------------------------

  10: #

  11: # Use a descriptive name for the node:

  12: #

  13: node.name: es-02

  14: node.master: true

  15: node.data: true

  16: #

  17: # ----------------------------------- Paths ------------------------------------

  18: #

  19: # Path to directory where to store the data (separate multiple locations by comma):

  20: #

  21: # path.data: /path/to/data

  22: #

  23: # Path to log files:

  24: #

  25: # path.logs: /path/to/logs

  26: #

  27: # ----------------------------------- Memory -----------------------------------

  28: #

  29: # ...

  30: #

  31: # ---------------------------------- Network -----------------------------------

  32: #

  33: # Set the bind address to a specific IP (IPv4 or IPv6):

  34: #

  35: network.host: 192.168.1.3

  36: #

  37: # Set a custom port for HTTP:

  38: #

  39: http.port: 9200

  40: transport.tcp.port: 9300

  41: #

  42: # --------------------------------- Discovery ----------------------------------

  43: #

  44: # Pass an initial list of hosts to perform discovery when new node is started:

  45: # The default list of hosts is ["127.0.0.1", "[::1]"]

  46: #

  47: discovery.zen.ping.unicast.hosts: ["192.168.1.2:9300"]

  48: #

  49: # ---------------------------------- Gateway -----------------------------------

  50: #

  51: # ...

  52: #

  53: # ---------------------------------- Various -----------------------------------

  54: # ...

  55:  

  56: index:

  57:   analysis:

  58:     tokenizer:

  59:       my_pinyin:

  60:         type: pinyin

  61:         first_letter: prefix

  62:         padding_char: ''

  63:       pinyin_first_letter:

  64:         type: pinyin

  65:         first_letter: only

  66:       mmseg_maxword:

  67:         type: mmseg

  68:         seg_type: max_word

  69:       mmseg_complex:

  70:         type: mmseg

  71:         seg_type: complex

  72:       mmseg_simple:

  73:         type: mmseg

  74:         seg_type: simple

  75:       semicolon_spliter:

  76:         type: pattern

  77:         pattern: ";"

  78:       pct_spliter:

  79:         type: pattern

  80:         pattern: "[%]+"

  81:       ngram_1_to_2:

  82:         type: nGram

  83:         min_gram: 1

  84:         max_gram: 2

  85:       ngram_1_to_3:

  86:         type: nGram

  87:         min_gram: 1

  88:         max_gram: 3

  89:     filter:

  90:       ngram_min_3:

  91:         max_gram: 10

  92:         min_gram: 3

  93:         type: nGram

  94:       ngram_min_2:

  95:         max_gram: 10

  96:         min_gram: 2

  97:         type: nGram

  98:       ngram_min_1:

  99:         max_gram: 10

 100:         min_gram: 1

 101:         type: nGram

 102:       min2_length:

 103:         min: 2

 104:         max: 4

 105:         type: length

 106:       min3_length:

 107:         min: 3

 108:         max: 4

 109:         type: length

 110:       pinyin_first_letter:

 111:         type: pinyin

 112:         first_letter: only

 113:     analyzer:

 114:       lowercase_keyword:

 115:         type: custom

 116:         filter:

 117:         - lowercase

 118:         tokenizer: standard

 119:       lowercase_keyword_ngram_min_size1:

 120:         type: custom

 121:         filter:

 122:         - lowercase

 123:         - stop

 124:         - trim

 125:         - unique

 126:         tokenizer: nGram

 127:       lowercase_keyword_ngram_min_size2:

 128:         type: custom

 129:         filter:

 130:         - lowercase

 131:         - min2_length

 132:         - stop

 133:         - trim

 134:         - unique

 135:         tokenizer: nGram

 136:       lowercase_keyword_ngram_min_size3:

 137:         type: custom

 138:         filter:

 139:         - lowercase

 140:         - min3_length

 141:         - stop

 142:         - trim

 143:         - unique

 144:         tokenizer: ngram_1_to_3

 145:       lowercase_keyword_ngram:

 146:         type: custom

 147:         filter:

 148:         - lowercase

 149:         - stop

 150:         - trim

 151:         - unique

 152:         tokenizer: ngram_1_to_3

 153:       lowercase_keyword_without_standard:

 154:         type: custom

 155:         filter:

 156:         - lowercase

 157:         tokenizer: keyword

 158:       lowercase_whitespace:

 159:         type: custom

 160:         filter:

 161:         - lowercase

 162:         tokenizer: whitespace

 163:       ik:

 164:         alias:

 165:         - ik_analyzer

 166:         type: ik

 167:       ik_max_word:

 168:         type: ik

 169:         use_smart: false

 170:       ik_smart:

 171:         type: ik

 172:         use_smart: true

 173:       mmseg:

 174:         alias:

 175:         - mmseg_analyzer

 176:         type: mmseg

 177:       mmseg_maxword:

 178:         type: custom

 179:         filter:

 180:         - lowercase

 181:         tokenizer: mmseg_maxword

 182:       mmseg_complex:

 183:         type: custom

 184:         filter:

 185:         - lowercase

 186:         tokenizer: mmseg_complex

 187:       mmseg_simple:

 188:         type: custom

 189:         filter:

 190:         - lowercase

 191:         tokenizer: mmseg_simple

 192:       comma_spliter:

 193:         type: pattern

 194:         pattern: "[,|\\s]+"

 195:       pct_spliter:

 196:         type: pattern

 197:         pattern: "[%]+"

 198:       custom_snowball_analyzer:

 199:         type: snowball

 200:         language: English

 201:       simple_english_analyzer:

 202:         type: custom

 203:         tokenizer: whitespace

 204:         filter:

 205:         - standard

 206:         - lowercase

 207:         - snowball

 208:       edge_ngram:

 209:         type: custom

 210:         tokenizer: edgeNGram

 211:         filter:

 212:         - lowercase

 213:       pinyin_ngram_analyzer:

 214:         type: custom

 215:         tokenizer: my_pinyin

 216:         filter:

 217:         - lowercase

 218:         - nGram

 219:         - trim

 220:         - unique

 221:       pinyin_first_letter_analyzer:

 222:         type: custom

 223:         tokenizer: pinyin_first_letter

 224:         filter:

 225:         - standard

 226:         - lowercase

 227:       pinyin_first_letter_keyword_analyzer:

 228:         alias:

 229:         - pinyin_first_letter_analyzer_keyword

 230:         type: custom

 231:         tokenizer: keyword

 232:         filter:

 233:         - pinyin_first_letter

 234:         - lowercase

 235:       path_analyzer: #used for tokenize :/something/something/else

 236:         type: custom

 237:         tokenizer: path_hierarchy

 238:  

 239: #index.analysis.analyzer.default.type: mmseg

 240: index.analysis.analyzer.default.type: ik

说明:

  • 第7行,也是指定了集群名称;
  • 第13行,指定了节点名称为 es-02(主机名)
  • 第14和15行,指定了该节点可能成为 master 节点,还可以是数据节点;
  • 第35行,指定节点IP地址为 192.168.1.3;
  • 第39行,指定http端口,你使用head、kopf等相关插件使用的端口;
  • 第40行,集群内部通信端口,用于节点发现等;

上面的配置master也是这么配置的。

  • 第47行,跟master节点配置不一样了。这里直接告诉该的节点,可能的master节点是什么。

参考资料


ELK——Elasticsearch 搭建集群经验的更多相关文章

  1. ELK——Elasticsearch 搭建集群经验

    本文内容 背景 ES集群中第一个master节点 ES slave节点 迁移到:http://www.bdata-cap.com/newsinfo/1712679.html 本文总结 Elastics ...

  2. 搭建ELK日志分析平台(上)—— ELK介绍及搭建 Elasticsearch 分布式集群

    笔记内容:搭建ELK日志分析平台(上)-- ELK介绍及搭建 Elasticsearch 分布式集群笔记日期:2018-03-02 27.1 ELK介绍 27.2 ELK安装准备工作 27.3 安装e ...

  3. Elastic Stack之ElasticSearch分布式集群yum方式搭建

    Elastic Stack之ElasticSearch分布式集群yum方式搭建 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.搜索引擎及Lucene基本概念 1>.什么 ...

  4. 关于elasticsearch安装及搭建集群时候的错误

    1,在Windows上解压后启动elasticsearch后可能cmd中会抛出java 无法初始话异常,网上查询必须用的是jdk1.8以上,可是本人用的 就是jdk1.8啊,半天解决无果,最后重新安装 ...

  5. sentinel搭建redis集群经验总结

    一.protected-mode默认情况下,redis node和sentinel的protected-mode都是yes,在搭建集群时,若想从远程连接redis集群,需要将redis node和se ...

  6. ES 31 - 从0开始搭建Elasticsearch生产集群

    目录 1 配置环境 1.1 服务器IP映射 1.2 配置各节点的ssh免密通信 1.3 安装JDK并配置环境变量 2 部署单节点服务 3 部署集群服务 4 启动集群中的所有节点 4.2 启动各个节点中 ...

  7. elasticsearch跨集群数据迁移

    写这篇文章,主要是目前公司要把ES从2.4.1升级到最新版本7.8,不过现在是7.9了,官方的文档:https://www.elastic.co/guide/en/elasticsearch/refe ...

  8. Elastic Stack之ElasticSearch分布式集群二进制方式部署

    Elastic Stack之ElasticSearch分布式集群二进制方式部署 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必大家都知道ELK其实就是Elasticsearc ...

  9. 架构之路:nginx与IIS服务器搭建集群实现负载均衡(三)

    参考网址:https://blog.csdn.net/zhanghan18333611647/article/details/50811980 [前言] 在<架构之路:nginx与IIS服务器搭 ...

随机推荐

  1. jquery实现tab页切换显示div

    1.jQuery实现tab切换显示代码实现 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" &q ...

  2. UIMenuController 实现长按显示自定义菜单功能

    这段时间在集成使用融云聊天功能的时候,想自定义消息cell的长按的菜单,在网上查了查,这是根据 UIMenuController 实现的.具体代码如下,我是使用一个btn实现的 首先创建一个btn,并 ...

  3. 进程调度算法Linux进程调度算法

    这次介绍一下操作系统的进程调度算法 操作系统的调度分为三种:1.远程调度(创建新进程):2.中程调度(交换功能的一部分):3.短程调度(下次执行哪个进程) 这次讲述的就是短程调度,可以简单的看作咱们平 ...

  4. CAST和CONVERT差别与联系

    CAST和CONVERT:都是将一种数据类型转换成为另一种数据类型. CAST: CAST ( expression AS data_type [ ( length ) ] ) EG: )) ) as ...

  5. andorid lint

    (一)Lint简介 Android SDK提供了一个代码扫描工具,称为lint.可以帮助您轻松地识别并纠正问题与结构质量的代码,不必执行应用程序或编写任何测试用例.每个问题检测到该工具报告的一个描述消 ...

  6. JMeter入门

    下载及安装 下载地址:http://jmeter.apache.org/download_jmeter.cgi 直接下载Release版本,解压即可使用 MAC.Linux中直接运行:jmeter文件 ...

  7. MS对WCF配置中security节点的解释

    摘录地址:http://msdn.microsoft.com/zh-CN/library/azure/ms731347 <basicHttpBinding> 的 <security& ...

  8. C#设计模式(20)——策略者模式(Stragety Pattern)

    一.引言 前面主题介绍的状态模式是对某个对象状态的抽象,而本文要介绍的策略模式也就是对策略进行抽象,策略的意思就是方法,所以也就是对方法的抽象,下面具体分享下我对策略模式的理解. 二.策略者模式介绍 ...

  9. 转:判断DATASET是否为空

    http://blog.sina.com.cn/jiangshuqin2010 1,if(ds == null) 这是判断内存中的数据集是否为空,说明DATASET为空,行和列都不存在!! 2,if( ...

  10. 你在用什么思想编码:事务脚本 OR 面向对象?

    最近在公司内部做技术交流的时候,说起技能提升的问题,调研大家想要培训什么,结果大出我意料,很多人想要培训:面向对象编码.于是我抛出一个问题:你觉得我们现在的代码是面向对象的吗?有人回答:是,有人回答否 ...