上一章完成了c#访问hbase的sdk封装,接下来以一个具体Demo对sdk进行测试验证。场景:每5秒抓取指定股票列表的实时价格波动行情,数据下载后,一方面实时刷新UI界面,另一方面将数据放入到在内存中模拟的MQ (实际生产情况,可用kafka等集群代替)->存入HBase数据库。提供按指定时间范围股票价格数据查询。

目录:

  • 示例说明
  • 示例效果图
  • rest server运行状态检查
  • 获取股票实时数据代码
  • 数据持续化至Hbase代码
  • 从HBase读取数据代码

示例说明:

  • 在Hbase 中创建两个表,分别为:
  1. StocksInfo (股票信息表,用来存储设置的股票代码、股票名称)
  2. StockRealInfo (股票实时行情数据,包含开盘价、当前价、最高价、最低价、五档竞买、卖单价和数量、成交单价、数量、涨跌幅等)
  • 每5秒钟抓取StocksInfo表中所有股票的数据,自动更新UI,持续化到HBase;支持增加、删除要监控的股票列表。
  • 提供按指定时间范围从hbase中查询历史数据

示例效果图:

  • 历史数据查询:

rest server运行状态检查:

  • 在 HDP2.4安装(五):集群及组件安装 章节,Hbase 主机安装在 hdp4 192.168.2.21 上,使用xshell 工具连接到hbase master(hdp4)
  • 查看8080端口是否正常,也可从 ambari UI 界面查看HBase状态,如图:

获取股票实时数据代码:

  •  好多的网站提供股票实时交易数据的下载,我选择的是从 hq.sina 下载,注意抓取数据的频度不要设置的太高,否则你的IP可能会被封掉,代码如下:

    public class SnatchFormSina
    {
    #region SnatchFormSina HttpClient client; private const string dataurl = "http://hq.sinajs.cn/list={0}"; public SnatchFormSina()
    {
    this.client = new HttpClient();
    } /// <summary>
    ///
    /// </summary>
    public static SnatchFormSina Current
    {
    get {
    return new SnatchFormSina();
    }
    } #endregion #region GetCurrentInfos /// <summary>
    ///
    /// </summary>
    /// <param name="stockIDs"></param>
    /// <returns></returns>
    public async Task<List<StockRealInfo>> GetCurrentInfosAsync(List<string> stockIDs)
    {
    List<StockRealInfo> list = new List<StockRealInfo>();
    string dataUrl = this.ParseStockIDs(stockIDs);
    dataUrl = dataUrl.Substring(, dataUrl.Length - ); string realInfo = await this.client.GetStringAsync(dataUrl);
    string[] infos = realInfo.Split('\n'); StockRealInfo stockInfo;
    foreach (string info in infos)
    {
    if (string.IsNullOrEmpty(info))
    continue; stockInfo = new StockRealInfo(info);
    stockInfo.ID = SimulatorCache.StockAccount[stockInfo.Name];
    SimulatorCache.StockInfos[stockInfo.ID] = stockInfo;
    list.Add(stockInfo);
    } return list;
    } #endregion #region ParseStockIDs /// <summary>
    ///
    /// </summary>
    /// <param name="stockIDs"></param>
    /// <returns></returns>
    private string ParseStockIDs(List<string> stockIDs)
    {
    StringBuilder sb = new StringBuilder();
    foreach(string id in stockIDs)
    {
    if (id.Substring(, ) == "")//上海是600打头
    {
    sb.Append(string.Format("sh{0},", id));
    }
    else if (id.Substring(, ) == "")//上海基金
    {
    sb.Append(string.Format("sh{0},", id));
    }
    else //if (stockIDs.Substring(0, 2) == "00")//深圳
    {
    sb.Append(string.Format("sz{0},", id));
    }
    } sb[sb.Length - ].ToString().Replace(",", ""); return string.Format(dataurl, sb.ToString());
    } #endregion #region ValiateStockID /// <summary>
    ///
    /// </summary>
    /// <param name="stockIDs"></param>
    /// <returns></returns>
    public async Task<string> ValiateStockID(string stockID)
    {
    string name = string.Empty;
    string dataUrl = this.ParseStockIDs(new List<string> { stockID });
    dataUrl = dataUrl.Substring(, dataUrl.Length - ); string realInfo = await this.client.GetStringAsync(dataUrl);
    string[] infos = realInfo.Split('\n'); StockRealInfo stockInfo;
    foreach (string info in infos)
    {
    if (string.IsNullOrEmpty(info))
    continue; stockInfo = new StockRealInfo(info);
    name = stockInfo.Name;
    } return name;
    } #endregion
    }

数据持续化到Hbase代码示例:

  • 代码中Utils.HBaseClient 是在一个工具类里面创建一个HBaseClient实例

    public class StockRealWriter
    {
    #region StockRealWriter Queue<StockRealInfo> queue = new Queue<StockRealInfo>(); // use multithread write
    Thread writerThread;
    bool threadRunning = true; const string HBASESTOCKTBLNAME = "StockRealInfo"; public StockRealWriter()
    {
    // Start a thread for writting to HBase
    Task task = new Task(WriterThreadFunction);
    task.Start();
    } ~StockRealWriter()
    {
    threadRunning = false;
    } #endregion #region WriterThreadFunction /// <summary>
    /// WriterThreadFunction
    /// </summary>
    public void WriterThreadFunction()
    {
    while (threadRunning)
    {
    if (queue.Count > )
    {
    lock (queue)
    {
    CellSet set = new CellSet();
    do
    {
    StockRealInfo stock = queue.Dequeue();
    this.CreateStockByRealInfos(set, stock);
    } while (queue.Count > ); Utils.HBaseClient.StoreCellsAsync(HBASESTOCKTBLNAME, set);
    }
    } Thread.Sleep();
    }
    } #endregion #region CreateStockByRealInfos /// <summary>
    ///
    /// </summary>
    /// <param name="set"></param>
    /// <param name="info"></param>
    private void CreateStockByRealInfos(CellSet set, StockRealInfo info)
    {
    string key = string.Format("{0}_{1}_{2}", info.ID, info.Date, info.Time);
    var row = new CellSet.Row { key = Encoding.UTF8.GetBytes(key) }; var value = new Cell { column = Encoding.UTF8.GetBytes("d:ID"), data = Encoding.UTF8.GetBytes(info.ID) };
    row.values.Add(value); value = new Cell { column = Encoding.UTF8.GetBytes("d:Name"), data = Encoding.UTF8.GetBytes(info.Name) };
    row.values.Add(value); //今日开盘价
    value = new Cell { column = Encoding.UTF8.GetBytes("d:TodayOpen"), data = Encoding.UTF8.GetBytes(info.TodayOpen) };
    row.values.Add(value); //昨日收盘价
    value = new Cell { column = Encoding.UTF8.GetBytes("d:YesterdayClose"), data = Encoding.UTF8.GetBytes(info.YesterdayClose) };
    row.values.Add(value); //当前价格
    value = new Cell { column = Encoding.UTF8.GetBytes("d:Current"), data = Encoding.UTF8.GetBytes(info.Current) };
    row.values.Add(value); //今日最高价
    value = new Cell { column = Encoding.UTF8.GetBytes("d:High"), data = Encoding.UTF8.GetBytes(info.High) };
    row.values.Add(value); //今日最低价
    value = new Cell { column = Encoding.UTF8.GetBytes("d:Low"), data = Encoding.UTF8.GetBytes(info.Low) };
    row.values.Add(value); //竟买价 买1
    value = new Cell { column = Encoding.UTF8.GetBytes("d:Buy"), data = Encoding.UTF8.GetBytes(info.Buy) };
    row.values.Add(value); //竟卖价 卖1
    value = new Cell { column = Encoding.UTF8.GetBytes("d:Sell"), data = Encoding.UTF8.GetBytes(info.Sell) };
    row.values.Add(value); // 成交数 单位股数 通常除于100成为手
    value = new Cell { column = Encoding.UTF8.GetBytes("d:VolAmount"), data = Encoding.UTF8.GetBytes(info.VolAmount) };
    row.values.Add(value); // 成交多少钱,单位元
    value = new Cell { column = Encoding.UTF8.GetBytes("d:VolMoney"), data = Encoding.UTF8.GetBytes(info.VolMoney) };
    row.values.Add(value); // 日期
    value = new Cell { column = Encoding.UTF8.GetBytes("d:Date"), data = Encoding.UTF8.GetBytes(info.Date) };
    row.values.Add(value); // 时间
    value = new Cell { column = Encoding.UTF8.GetBytes("d:Time"), data = Encoding.UTF8.GetBytes(info.Time) };
    row.values.Add(value); // 差额
    value = new Cell { column = Encoding.UTF8.GetBytes("d:Diff"), data = Encoding.UTF8.GetBytes(info.Diff) };
    row.values.Add(value); // 百分比
    value = new Cell { column = Encoding.UTF8.GetBytes("d:DiffPrec"), data = Encoding.UTF8.GetBytes(info.DiffPrec) };
    row.values.Add(value); DataRow buyInfo;
    for(int i=;i<;i++)
    {
    buyInfo = info.BuyList.Rows[i]; value = new Cell { column = Encoding.UTF8.GetBytes(string.Format("d:Price0{0}",i.ToString())), data = Encoding.UTF8.GetBytes(Convert.ToString(buyInfo["Price"])) };
    row.values.Add(value); value = new Cell { column = Encoding.UTF8.GetBytes(string.Format("d:Amount0{0}", i.ToString())), data = Encoding.UTF8.GetBytes(Convert.ToString(buyInfo["Amount"])) };
    row.values.Add(value);
    } DataRow sellInfo;
    for (int i = ; i < ; i++)
    {
    sellInfo = info.SellList.Rows[i]; value = new Cell { column = Encoding.UTF8.GetBytes(string.Format("d:Price1{0}", i.ToString())), data = Encoding.UTF8.GetBytes(Convert.ToString(sellInfo["Price"])) };
    row.values.Add(value); value = new Cell { column = Encoding.UTF8.GetBytes(string.Format("d:Amount1{0}", i.ToString())), data = Encoding.UTF8.GetBytes(Convert.ToString(sellInfo["Amount"])) };
    row.values.Add(value);
    } set.rows.Add(row);
    } #endregion #region WriteStock /// <summary>
    ///
    /// </summary>
    /// <param name="stockInfo"></param>
    public void WriteStock(List<StockRealInfo> stockInfos)
    {
    lock (queue)
    {
    foreach(var stockInfo in stockInfos)
    {
    queue.Enqueue(stockInfo);
    }
    }
    } #endregion
    }

从HBase读取数据代码:

  • 代码中 Scanner 参数是指设置的查询范围 (设置StartRow、EndRow、Batch等参数)

    public class StockRealReader
    {
    #region StockRealReader const string HBASESTOCKTBLNAME = "StockRealInfo"; public StockRealReader()
    { } #endregion #region QueryStockRealAsync public async Task<List<StockRealInfo>> QueryStockRealAsync(Scanner query)
    {
    List<StockRealInfo> list = new List<StockRealInfo>(); ScannerInformation info = await Utils.HBaseClient.CreateScannerAsync(HBASESTOCKTBLNAME, query); CellSet next;
    while ((next = await Utils.HBaseClient.ScannerGetNextAsync(info)) != null)
    {
    StockRealInfo realInfo;
    foreach (CellSet.Row row in next.rows)
    {
    realInfo = new StockRealInfo(); //开盘价
    var temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:TodayOpen");
    realInfo.TodayOpen = Encoding.UTF8.GetString(temp.data); //昨日收盘价
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:YesterdayClose");
    realInfo.YesterdayClose = Encoding.UTF8.GetString(temp.data); //当前价格
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:Current");
    realInfo.Current = Encoding.UTF8.GetString(temp.data); //今日最高价
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:High");
    realInfo.High = Encoding.UTF8.GetString(temp.data); //今日最低价
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:Low");
    realInfo.Low = Encoding.UTF8.GetString(temp.data); //竟买价 买1
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:Buy");
    realInfo.Buy = Encoding.UTF8.GetString(temp.data); //竟卖价 卖1
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:Sell");
    realInfo.Sell = Encoding.UTF8.GetString(temp.data); //成交数 单位股数 通常除于100成为手
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:VolAmount");
    realInfo.VolAmount = Encoding.UTF8.GetString(temp.data); //成交多少钱,单位元
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:VolMoney");
    realInfo.VolMoney = Encoding.UTF8.GetString(temp.data); //日期
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:Date");
    realInfo.Date = Encoding.UTF8.GetString(temp.data); //时间
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:Time");
    realInfo.Time = Encoding.UTF8.GetString(temp.data); //差额
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:Diff");
    realInfo.Diff = Encoding.UTF8.GetString(temp.data); //百分比
    temp = row.values.Find(c => Encoding.UTF8.GetString(c.column) == "d:DiffPrec");
    realInfo.DiffPrec = Encoding.UTF8.GetString(temp.data); list.Add(realInfo); }
    } return list;
    } #endregion
    }

HBase(二): c#访问HBase之股票行情Demo的更多相关文章

  1. HBase(一): c#访问hbase组件开发

    HDP2.4安装系列介绍了通过ambari创建hbase集群的过程,但工作中一直采用.net的技术路线,如何去访问基于Java搞的Hbase呢? Hbase提供基于Java的本地API访问,同时扩展了 ...

  2. Pyspark访问Hbase

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl/p/7347167.html 转载请注明出处 记录自己最近抽空折腾虚拟机环境时用spark2.0的pyspark ...

  3. HBase二次开发之搭建HBase调试环境,如何远程debug HBase源代码

    版本 HDP:3.0.1.0 HBase:2.0.0 一.前言 之前的文章也提到过,最近工作中需要对HBase进行二次开发(参照HBase的AES加密方法,为HBase增加SMS4数据加密类型).研究 ...

  4. 使用C#通过Thrift访问HBase

    前言 因为项目需要要为客户程序提供C#.Net的HBase访问接口,而HBase并没有提供原生的.Net客户端接口,可以通过启动HBase的Thrift服务来提供多语言支持. Thrift介绍 环境 ...

  5. Hbase记录-client访问zookeeper大量断开以及参数调优分析(转载)

    1.hbase client配置参数 超时时间.重试次数.重试时间间隔的配置也比较重要,因为默认的配置的值都较大,如果出现hbase集群或者RegionServer以及ZK关掉,则对应用程序是灾难性的 ...

  6. 使用C#和Thrift来访问Hbase实例

    今天试着用C#和Thrift来访问Hbase,主要参考了博客园上的这篇文章.查了Thrift,Hbase的资料,结合博客园的这篇文章,终于搞好了.期间经历了不少弯路,下面我尽量详细的记录下来,免得大家 ...

  7. windows平台下用C#访问HBase

    Hadoop中的HBase有多种数据访问方式,ubuntu里可以用hbase shell查看操作hbase数据库,但windows平台下需要用thrift对它进行访问. 例如hadoop安装在/usr ...

  8. JAVA API访问Hbase org.apache.hadoop.hbase.client.RetriesExhaustedException: Failed after attempts=32

    Java使用API访问Hbase报错: 我的hbase主节点是spark1   java代码访问hbase的时候写的是ip 结果运行程序报错 不能够识别主机名 修改主机名     修改主机hosts文 ...

  9. CDH 6.0.1 版本 默认配置下 HUE | happybase 无法访问 Hbase 的问题

    第一个问题 HUE 无法直接连接到 HBase 在默认配置下 CDH 6.0.1 版本下的 HBase2.0 使用了默认配置 hbase.regionserver.thrift.compact = T ...

随机推荐

  1. windows服务部署与卸载

    同事问到windows service的东东,现在整理一下,用c#如何创建一个windows service,以及如何调试.部署.卸载. 一.创建windows service 1. 打开VS2008 ...

  2. session过期时ajax请求刷新浏览器

    ajax前置处理实现异步请求session过期时跳转登录页面 function checkLogin(json) { if (typeof(json) === 'string' && ...

  3. Xen虚拟机磁盘镜像模板制作(四)—CentOS 7

    在<Xen虚拟机磁盘镜像模板制作(三)—CentOS 7>一文中,我们已经成功制作出了 CentOS7 磁盘镜像.下面我们说明下如何通过它来生成目标虚拟机,同时测试下之前制作好的虚拟机磁盘 ...

  4. iOS学习笔记---oc语言第四天

    字符串 数组 一.使用苹果帮助文档 学会使⽤用苹果帮助⽂文档是开发者的⼀一项技能 Inherits from 继承⾃自 Conforms to 遵循什么协议 Framework 属于哪个框架 Avai ...

  5. String的常规使用集合

    今天先附上代码君: package com.jacob.javase; import java.io.UnsupportedEncodingException; /* *探讨String:  *  * ...

  6. spark Streaming的Receiver和Direct的优化对比

    Direct 1.简化并行读取:如果要读取多个partition,不需要创建多个输入DStream然后对它们进行union操作.Spark会创建跟Kafka partition一样多的RDD part ...

  7. 【P1813】8的倍数

    容斥原理,居然没想到……要补一下数论了 原题: 小x最近对数字8很感兴趣,有8进制,2008奥运会之类的.现在小x想知道,在[x,y]区间里,有多少个数能被8整除.小y觉得题目太简单,于是给出n个其他 ...

  8. C语言二重指针与malloc

    (内容主要源于网上,只是加入了些自己的剖析) 假设有一个二重指针: char **p; 同时有一个指针数组 char *name[4]; 如何引用p呢? 首先我们有程序代码如下 #include &l ...

  9. 《Linux与Qt程序设计》知识框架

    本文主要是通过一本书来大致了解Qt开发的框架,不对具体内容做详细分析. 1.首先弄清楚概念:定义->以自己的话理解是什么-> 实现的是什么功能->用在哪些地方 2.前面认识到的知识点 ...

  10. 编写linux驱动所用到的头文件(转)

    转自:http://blog.csdn.net/lufeiop02/article/details/6448497 关于linux驱动(应用)程序头文件使用 收藏 驱动程序: #include < ...