看我如何快速学习.Net(高可用数据采集平台)

最近文章:高可用数据采集平台(如何玩转3门语言php+.net+aauto)高并发数据采集的架构应用(Redis的应用)

项目文档:关键词匹配项目深入研究(二)- 分表思想的引入

吐槽:本人也是非常讨厌拿来主义的,有些培训每个细节都提到过,主管还找我要实际案例,而不是去安排合适的人去做这件事情,有点过于拿来主义了,有点担心。

好消息的是:高并发数据采集的架构应用(Redis的应用)团队已经实现了,不过有部分代码还是我写的,值得喝彩下,说明团队的能力还是不错的。

最近有时间,我也是用.net完成高可用数据采集平台(如何玩转3门语言php+.net+aauto)服务的编码工作。

正文开始

要想快速学习某一件事情,我们就得必须做好规划。

首先我们先来分析下要实现该项目需要哪些方面的技术,我们从哪里开始分析呢,当然有系统分析师帮你做啦!

所需的技术

1. Microsoft Studio 2010 IDE以及.Net Framework基础知识的了解

2. 如何利用C#创建服务,服务安装以及卸载

3. SQLite的基础应用以及C#如何使用SQLite

4. C#定时器的应用

5. C#的多线程应用以及线程池的应用

6. 操作系统信号量,互斥同步锁概念以及C#如何使用信号量、互斥同步锁

7. C#文件操作,ini配置文件读取技术

8. C# WEB API的调用,以及异步处理知识和C# TASK的了解应用

9. 数据传输解析技术,以及C#如何解析JSON

10. 其它常用应用,比如DataSet、DataTable、DataRow、Dictionary、List、KeyValuePair、String等

这些点看起来好恐怖,要想做好应用这些只是小小的一部分,但相对于菜鸟或者学生们就等于天书了,但是我只有一个星期的事情。

只要我们有目的去做事,任何事都不会有阻碍,废话少说,等下闲我啰嗦了。

1. Microsoft Studio 2010 IDE以及.Net Framework基础知识的了解

     这点我竟然列为了重点,有些人有可能对这点不重视,但是我相信很多有经验的人都会同我一样非常重视这点。

Microsoft Studio 2010 IDE都不用说了,这个大家都是专家,我为什么会选择博客园写文章,是因为我在上学的时候看了一本博客园出版的书,讲的是设计模式的应用,觉得非常的不错,当时博客园是.Net技术平台的佼佼者。

Microsoft Studio 2010 IDE最主要的一点,就是选择框架,选择项目适合的框架。

.Net Framework 主要也是注意下为什么有那么多版本,了解下他们互相是否有关系,比如从2.0升到4.0是否能够平稳的过渡。

   2. 如何利用C#创建服务,服务安装以及卸载

    我也是看了一篇博客而学来的,非常不错,我也把地址贴出来:http://www.cnblogs.com/aierong/archive/2012/05/28/2521409.html

我也是主要用了(a) 利用.net框架类ServiceBase,步骤参考上面博客的地址:安装的时候注意下选择好对应版本的installutil。

    代码贴出来

public partial class MainService : ServiceBase
    {
        readonly System.Timers.Timer _timer_request;

        readonly System.Timers.Timer _timer_upload;

        WorkProcess work = new WorkProcess(10);

        public MainService()
        {
            InitializeComponent();

            //install db table
            TaskModel.install();

            _timer_upload  = _timer_request = new System.Timers.Timer(5000)
            {
                AutoReset = true,
                Enabled = true
            };

            _timer_request.Elapsed += delegate(object sender, ElapsedEventArgs e)
            {
                Logger.log("Start Request Data From Api");

                try
                {
                    TaskResponse response = TaskFactory.createFromApi();
                    TaskModel.save(response);
                }
                catch (Exception ex)
                {
                    Logger.error(ex.Message);
                }

                Logger.log("End Request Data From Api");
            };

            _timer_upload.Elapsed += delegate(object sender, ElapsedEventArgs e)
            {
                Logger.log("Start Upload Data To Api");
                try
                {
                    if (!work.wait())
                    {
                        work.doing();
                    }
                }
                catch (Exception ex)
                {
                    Logger.error(ex.Message);
                }
                Logger.log("End Upload Data To Api");

            };

        }

        protected override void OnStart(string[] args)
        {
            _timer_request.Enabled = true;
            _timer_upload.Enabled = true;
        }

        protected override void OnStop()
        {
            _timer_request.Enabled = false;
            _timer_upload.Enabled = false;
        }
    }

  

3. SQLite的基础应用以及C#如何使用SQLite

   也是一样,有博客就是好,推荐代码直接拷贝一份过来。http://www.cnblogs.com/OnlyVersion/p/3746086.html

我也贴个相对精简的吧。

class DB
    {
        /// <summary>
        /// 获得连接对象
        /// </summary>
        /// <returns>SQLiteConnection</returns>
        public static SQLiteConnection GetSQLiteConnection(){

            string str = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var con = new SQLiteConnection("Data Source=" + str + @"\" + "DataBase" + @"\" + "InfoServiceDb.db");
            return con;
       }

        /// <summary>
        /// 准备操作命令参数
        /// </summary>
        /// <param name="cmd">SQLiteCommand</param>
        /// <param name="conn">SQLiteConnection</param>
        /// <param name="cmdText">Sql命令文本</param>
        /// <param name="data">参数数组</param>
        private static void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, string cmdText, Dictionary<String, String> data)
        {
            if (conn.State != ConnectionState.Open)
                conn.Open();
            cmd.Parameters.Clear();
            cmd.Connection = conn;
            cmd.CommandText = cmdText;
            cmd.CommandType = CommandType.Text;
            cmd.CommandTimeout = 30;
            if (data != null && data.Count >= 1)
            {
                foreach (KeyValuePair<String, String> val in data)
                {
                    cmd.Parameters.AddWithValue(val.Key, val.Value);
                }
            }
        }

        /// <summary>
        /// 查询,返回DataSet
        /// </summary>
        /// <param name="cmdText">Sql命令文本</param>
        /// <param name="data">参数数组</param>
        /// <returns>DataSet</returns>
        public static DataSet ExecuteDataset(string cmdText, Dictionary<string, string> data)
        {
            var ds = new DataSet();
            using (SQLiteConnection connection = GetSQLiteConnection())
            {
                var command = new SQLiteCommand();
                PrepareCommand(command, connection, cmdText, data);
                var da = new SQLiteDataAdapter(command);
                da.Fill(ds);
            }
            return ds;
        }

        /// <summary>
        /// 查询,返回DataTable
        /// </summary>
        /// <param name="cmdText">Sql命令文本</param>
        /// <param name="data">参数数组</param>
        /// <returns>DataTable</returns>
        public static DataTable ExecuteDataTable(string cmdText, Dictionary<string, string> data)
        {
            var dt = new DataTable();
            using (SQLiteConnection connection = GetSQLiteConnection())
            {
                var command = new SQLiteCommand();
                PrepareCommand(command, connection, cmdText, data);
                SQLiteDataReader reader = command.ExecuteReader();
                dt.Load(reader);
            }
            return dt;
        }

        /// <summary>
        /// 返回一行数据
        /// </summary>
        /// <param name="cmdText">Sql命令文本</param>
        /// <param name="data">参数数组</param>
        /// <returns>DataRow</returns>
        public static DataRow ExecuteDataRow(string cmdText, Dictionary<string, string> data)
        {
            DataSet ds = ExecuteDataset(cmdText, data);
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                return ds.Tables[0].Rows[0];
            return null;
        }

        /// <summary>
        /// 执行数据库操作
        /// </summary>
        /// <param name="cmdText">Sql命令文本</param>
        /// <param name="data">传入的参数</param>
        /// <returns>返回受影响的行数</returns>
        public static int ExecuteNonQuery(string cmdText, Dictionary<string, string> data)
        {
            using (SQLiteConnection connection = GetSQLiteConnection())
            {
                var command = new SQLiteCommand();
                PrepareCommand(command, connection, cmdText, data);
                return command.ExecuteNonQuery();
            }
        }

        /// <summary>
        /// 返回SqlDataReader对象
        /// </summary>
        /// <param name="cmdText">Sql命令文本</param>
        /// <param name="data">传入的参数</param>
        /// <returns>SQLiteDataReader</returns>
        public static SQLiteDataReader ExecuteReader(string cmdText, Dictionary<string, string> data)
        {
            var command = new SQLiteCommand();
            SQLiteConnection connection = GetSQLiteConnection();
            try
            {
                PrepareCommand(command, connection, cmdText, data);
                SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
                return reader;
            }
            catch
            {
                connection.Close();
                command.Dispose();
                throw;
            }
        }

        /// <summary>
        /// 返回结果集中的第一行第一列,忽略其他行或列
        /// </summary>
        /// <param name="cmdText">Sql命令文本</param>
        /// <param name="data">传入的参数</param>
        /// <returns>object</returns>
        public static object ExecuteScalar(string cmdText, Dictionary<string, string> data)
        {
            using (SQLiteConnection connection = GetSQLiteConnection())
            {
                var cmd = new SQLiteCommand();
                PrepareCommand(cmd, connection, cmdText, data);
                return cmd.ExecuteScalar();
            }
        }
}

4. C#定时器的应用

  参考1.创建服务的代码

主要两个定时器:

1. 用于请求服务端要待处理事项

2. 用于上传已处理事项的数据到服务器。

5. C#的多线程应用以及线程池的应用

     多线程和线程池的概念这儿略过,本次应用只使用了.Net Framework中提供ThreadPool

ThreadPool:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html ,这篇博客很好的介绍了基础知识。

我也贴一下,本次应用的代码:

public class WorkProcess
    {
        public static int iCount = 0;
        public static int iMaxCount = 0;

        public WorkProcess(int MaxCount)
        {
            iMaxCount = MaxCount;
        }

        //线程池里的线程将调用Beta()方法
        public void execute(Object state)
        {
            Interlocked.Increment(ref iCount);
            try
            {
                TaskState taskState = (TaskState)state;
                string lockedStr = string.Format("task.locked.{0}.{1}", taskState.taskId, taskState.uploadId);

                lock (lockedStr)
                {
                    TaskUpload.work(taskState);
                }
                int iX = 10000;
                Thread.Sleep(iX);
            }
            catch (Exception e)
            {
                Logger.error(e.Message);
            }
            finally
            {
                Interlocked.Decrement(ref iCount);
            }

        }

        public bool wait()
        {
             int threadNumber = 0;
            //获取当前线程数
             threadNumber = Interlocked.Exchange(ref iCount, iCount);

             Logger.log(string.Format("Thread Num:{0}",threadNumber));

             if (threadNumber <= iMaxCount)
             {
                 return false;
             }
             return true;

        }

        public void doing()
        {
            string sql = "SELECT task.id as id,task_upload.id as uploadId FROM task LEFT JOIN task_upload ON task.id=task_upload.task_id WHERE status=:status AND upload_status=:upload_status LIMIT 10";
            Dictionary<string, string> data = new Dictionary<string, string>();
            data.Add(":status", "DONE");
            data.Add(":upload_status", "WAIT");
            DataTable dt = DB.ExecuteDataTable(sql, data);

            foreach (DataRow row in dt.Rows)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(this.execute), new TaskState((int)row["id"], (int)row["uploadId"]));
            }
        }
    }

6. 操作系统信号量,互斥同步锁概念以及C#如何使用信号量、互斥同步锁

   本次应用使用了信号量,主要作用是防止无限制的往线程池里面PUSH任务,适当的等待下任务的处理进度。

7. C#文件操作,ini配置文件读取技术

    本次应用主要使用文件存储一些必要的调试信息以及错误信息。

public class Logger
    {
        private static readonly string ErrorFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" +"logs"+@"\"+ "error.txt";
        private static readonly string LogFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" + "logs" + @"\" + "log.txt";

        public static void log(string msg)
        {
            StreamWriter sw = File.AppendText(LogFileName);
            sw.WriteLine(string.Format("{0}:{1}",DateTime.Now,msg));
            sw.Flush();
            sw.Close();
        }

        public static void error(string msg)
        {
            StreamWriter sw = File.AppendText(ErrorFileName);
            sw.WriteLine(string.Format("{0}:{1}", DateTime.Now, msg));
            sw.Flush();
            sw.Close();
        }
    }

Ini配置读取是为了更好的成为一个独立的构件,源码来源博客园的其他作者。

/// <summary>
    /// IniFiles的类
    /// </summary>
    public class IniFiles
    {
        public string FileName; //INI文件名
        //声明读写INI文件的API函数
        [DllImport("kernel32")]
        private static extern bool WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, byte[] retVal, int size, string filePath);

        public static IniFiles config(){

            string configFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)+@"\config.ini";

            return new IniFiles(configFileName);
        }

        //类的构造函数,传递INI文件名
        public IniFiles(string AFileName)
        {
            // 判断文件是否存在
            FileInfo fileInfo = new FileInfo(AFileName);
            //Todo:搞清枚举的用法
            if ((!fileInfo.Exists))
            { //|| (FileAttributes.Directory in fileInfo.Attributes))
                //文件不存在,建立文件
                System.IO.StreamWriter sw = new System.IO.StreamWriter(AFileName, false, System.Text.Encoding.Default);
                try
                {
                    sw.Write("#表格配置档案");
                    sw.Close();
                }
                catch
                {
                    throw (new ApplicationException("Ini文件不存在"));
                }
            }
            //必须是完全路径,不能是相对路径
            FileName = fileInfo.FullName;
        }
        //写INI文件
        public void WriteString(string Section, string Ident, string Value)
        {
            if (!WritePrivateProfileString(Section, Ident, Value, FileName))
            {
                throw (new ApplicationException("写Ini文件出错"));
            }
        }
        //读取INI文件指定
        public string ReadString(string Section, string Ident, string Default)
        {
            Byte[] Buffer = new Byte[65535];
            int bufLen = GetPrivateProfileString(Section, Ident, Default, Buffer, Buffer.GetUpperBound(0), FileName);
            //必须设定0(系统默认的代码页)的编码方式,否则无法支持中文
            string s = Encoding.GetEncoding(0).GetString(Buffer);
            s = s.Substring(0, bufLen);
            return s.Trim();
        }

        //读整数
        public int ReadInteger(string Section, string Ident, int Default)
        {
            string intStr = ReadString(Section, Ident, Convert.ToString(Default));
            try
            {
                return Convert.ToInt32(intStr);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return Default;
            }
        }

        //写整数
        public void WriteInteger(string Section, string Ident, int Value)
        {
            WriteString(Section, Ident, Value.ToString());
        }

        //读布尔
        public bool ReadBool(string Section, string Ident, bool Default)
        {
            try
            {
                return Convert.ToBoolean(ReadString(Section, Ident, Convert.ToString(Default)));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return Default;
            }
        }

        //写Bool
        public void WriteBool(string Section, string Ident, bool Value)
        {
            WriteString(Section, Ident, Convert.ToString(Value));
        }

        //从Ini文件中,将指定的Section名称中的所有Ident添加到列表中
        public void ReadSection(string Section, StringCollection Idents)
        {
            Byte[] Buffer = new Byte[16384];
            //Idents.Clear();

            int bufLen = GetPrivateProfileString(Section, null, null, Buffer, Buffer.GetUpperBound(0),
                  FileName);
            //对Section进行解析
            GetStringsFromBuffer(Buffer, bufLen, Idents);
        }

        private void GetStringsFromBuffer(Byte[] Buffer, int bufLen, StringCollection Strings)
        {
            Strings.Clear();
            if (bufLen != 0)
            {
                int start = 0;
                for (int i = 0; i < bufLen; i++)
                {
                    if ((Buffer[i] == 0) && ((i - start) > 0))
                    {
                        String s = Encoding.GetEncoding(0).GetString(Buffer, start, i - start);
                        Strings.Add(s);
                        start = i + 1;
                    }
                }
            }
        }
        //从Ini文件中,读取所有的Sections的名称
        public void ReadSections(StringCollection SectionList)
        {
            //Note:必须得用Bytes来实现,StringBuilder只能取到第一个Section
            byte[] Buffer = new byte[65535];
            int bufLen = 0;
            bufLen = GetPrivateProfileString(null, null, null, Buffer,
             Buffer.GetUpperBound(0), FileName);
            GetStringsFromBuffer(Buffer, bufLen, SectionList);
        }
        //读取指定的Section的所有Value到列表中
        public void ReadSectionValues(string Section, NameValueCollection Values)
        {
            StringCollection KeyList = new StringCollection();
            ReadSection(Section, KeyList);
            Values.Clear();
            foreach (string key in KeyList)
            {
                Values.Add(key, ReadString(Section, key, ""));
            }
        }
        ////读取指定的Section的所有Value到列表中,
        //public void ReadSectionValues(string Section, NameValueCollection Values,char splitString)
        //{  string sectionValue;
        //  string[] sectionValueSplit;
        //  StringCollection KeyList = new StringCollection();
        //  ReadSection(Section, KeyList);
        //  Values.Clear();
        //  foreach (string key in KeyList)
        //  {
        //    sectionValue=ReadString(Section, key, "");
        //    sectionValueSplit=sectionValue.Split(splitString);
        //    Values.Add(key, sectionValueSplit[0].ToString(),sectionValueSplit[1].ToString());

        //  }
        //}
        //清除某个Section
        public void EraseSection(string Section)
        {
            if (!WritePrivateProfileString(Section, null, null, FileName))
            {
                throw (new ApplicationException("无法清除Ini文件中的Section"));
            }
        }
        //删除某个Section下的键
        public void DeleteKey(string Section, string Ident)
        {
            WritePrivateProfileString(Section, Ident, null, FileName);
        }
        //Note:对于Win9X,来说需要实现UpdateFile方法将缓冲中的数据写入文件
        //在Win NT, 2000和XP上,都是直接写文件,没有缓冲,所以,无须实现UpdateFile
        //执行完对Ini文件的修改之后,应该调用本方法更新缓冲区。
        public void UpdateFile()
        {
            WritePrivateProfileString(null, null, null, FileName);
        }

        //检查某个Section下的某个键值是否存在
        public bool ValueExists(string Section, string Ident)
        {
            StringCollection Idents = new StringCollection();
            ReadSection(Section, Idents);
            return Idents.IndexOf(Ident) > -1;
        }

        //确保资源的释放
        ~IniFiles()
        {
            UpdateFile();
        }
    }

我们也是主要学习下使用方式就好了。

8. C# WEB API的调用,以及异步处理知识和C# TASK的了解应用

C# WEB API的调用也是参考了博客园的知识:http://www.cnblogs.com/r01cn/archive/2012/11/20/2779011.html

主要也是使用了HttpClient。

代码如下:

public static TaskResponse createFromApi()
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(
               new MediaTypeWithQualityHeaderValue("application/json")
             );
            string readUri = IniFiles.config().ReadString("uri","read","");
            HttpResponseMessage response = client.GetAsync(readUri).Result;

            if (response.IsSuccessStatusCode)
            {
                // Parse the response body. Blocking!
                var taskString = response.Content.ReadAsStringAsync().Result;

                StringReader sr = new StringReader(taskString.ToString());
                JsonSerializer serializer = new JsonSerializer();
                TaskResponse taskResponse = (TaskResponse)serializer.Deserialize(new JsonTextReader(sr),typeof(TaskResponse));

                Logger.log(string.Format("nick:{0},Type:{1}", taskResponse.nick, taskResponse.type));
                return taskResponse;
            }
            else
            {
                Logger.error(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
                throw new Exception(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
            }
        }

        public static bool upload(string jsonData)
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(
               new MediaTypeWithQualityHeaderValue("application/json")
             );

            string uploadUri = IniFiles.config().ReadString("uri", "upload", "");
            List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
            paramList.Add(new KeyValuePair<string, string>("data",jsonData));

            var response = client.PostAsync(uploadUri, new FormUrlEncodedContent(paramList)).Result;
            if (response.IsSuccessStatusCode)
            {
                var responseString = response.Content.ReadAsStringAsync().Result;
                Logger.log(responseString.ToString());
                return true;
            }
            else
            {
                Logger.error(string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase));
                return false;
            }

        }

9. 数据传输解析技术,以及C#如何解析JSON

   数据传输技术已经经历过很多时代,不过现在的时代用json还是相当比较普及的,比如现在的手机行业的普及,JSON的传输方式再一次被推向浪的高潮。

C# json解析,我使用了第三方包Newtonsoft.Json,原因很简单,我觉得易用,哪个好用我就选哪个。

使用方法参考 8.C# WEB API的调用,以及异步处理知识和C# TASK的了解应用

10. 其它常用应用,比如DataSet、DataTable、DataRow、Dictionary、List、KeyValuePair、String等

     因为这些是基础,多使用,摸清他们的关系,基本讲求到会用就行了,当然性能优化的另说了,你要纠结的话那就去纠结吧。

总结:

     要想成功做好一件事情,是要有目的的去做去学,像我这样能把所有的都列清楚,一步一步的走吧,相信你离成功将会不远了。

时间: 2024-10-01 02:38:39

看我如何快速学习.Net(高可用数据采集平台)的相关文章

高可用数据采集平台(如何玩转3门语言php+.net+aauto)

同类文章:高并发数据采集的架构应用(Redis的应用) 吐槽下:本人主程是PHP,团队里面也没有精通.net的人才,为了解决这个平台方案,还是费了一部分劲. 新年了,希望有个新的开始.技术+团队管理都有新的突破吧,在新的一年对自己好些,不能再继续搞基下去. 问题出发点: ´随着软件的日益强大,用户的使用需求越来越多,用户也希望众多数据进行整合,来达到资源的合理应用. ´有些数据资源需要抓取网页的形式来采集到数据. ´采集应用不统一,没有良好的管理程序,杂乱无章. ´采集应用经常性无响应,无相应的

高可用Hadoop平台-启航

1.概述 在上篇博客中,我们搭建了<配置高可用Hadoop平台>,接下来我们就可以驾着Hadoop这艘巨轮在大数据的海洋中遨游了.工欲善其事,必先利其器.是的,没错:我们开发需要有开发工具(IDE):本篇文章,我打算讲解如何搭建和使用开发环境,以及编写和讲解WordCount这个例子,给即将在Hadoop的海洋驰骋的童鞋入个门.上次,我在<网站日志统计案例分析与实现>中说会将源码放到Github,后来,我考虑了下,决定将<高可用的Hadoop平台>做一个系列,后面基于这

高可用Hadoop平台-实战

1.概述 今天继续<高可用的Hadoop平台>系列,今天开始进行小规模的实战下,前面的准备工作完成后,基本用于统计数据的平台都拥有了,关于导出统计结果的文章留到后面赘述.今天要和大家分享的案例是一个基于电商网站的用户行为分析,这里分析的指标包含以下指标: 统计每日PV 每日注册用户 每日IP 跳出用户 其他指标可以参考上述4个指标进行拓展,下面我们开始今天的分析之旅. 2.流程 首先,在开发之前我们需要注意哪些问题?我们不能盲目的按照自己的意愿去开发项目,这样到头来得不到产品的认可,我们的工作

高可用Hadoop平台-Ganglia安装部署

1.概述 最近,有朋友私密我,Hadoop有什么好的监控工具,其实,Hadoop的监控工具还是蛮多的.今天给大家分享一个老牌监控工具Ganglia,这个在企业用的也算是比较多的,Hadoop对它的兼容也很好,不过就是监控界面就不是很美观.下次给大家介绍另一款工具——Hue,这个界面官方称为Hadoop UI,界面美观,功能也比较丰富.今天,在这里主要给大家介绍Ganglia这款监控工具,介绍的内容主要包含如下: Ganglia背景 Ganglia安装部署.配置 Hadoop集群配置Ganglia

高可用Hadoop平台-Flume NG实战图解篇

1.概述 今天补充一篇关于Flume的博客,前面在讲解高可用的Hadoop平台的时候遗漏了这篇,本篇博客为大家讲述以下内容: Flume NG简述 单点Flume NG搭建.运行 高可用Flume NG搭建 Failover测试 截图预览 下面开始今天的博客介绍. 2.Flume NG简述 Flume NG是一个分布式,高可用,可靠的系统,它能将不同的海量数据收集,移动并存储到一个数据存储系统中.轻量,配置简单,适用于各种日志收集,并支持Failover和负载均衡.并且它拥有非常丰富的组件.Fl

Hadoop-2.4.1学习之高可用ResourceManager

在Hadoop-2.4之前,Yarn中的ResourceManager也是单点故障中的,就像Hadoop-1.x中的NameNode,由于Hadoop-2.X已经支持NameNode的HA(高可用性),那么自然也要在hadoop的某个版本中实现ResourceManager的HA,否则又会招致一些事后诸葛亮的诟病.本文将介绍RM的高可用性,并详细学习如何配置和使用该特性.就像NameNode的HA一样,ResourceManager的HA也是通过冗余的Active/Standby Resourc

Mysql数据库学习之高可用架构Atlas简析

Atlas是一个基于MySQL协议的数据中间层项目,在MySQL-Proxy 0.8.2版本基础上修改了大量bug,添加了很多功能特性.目前该项目很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条. Atlas的主要功能有: 1.读写分离:2.从库负载均衡:3.IP过滤:4.自动分表:5.DBA可平滑上下线DB:6.自动摘除宕机的DB. Atlas是一个位于应用程序与MySQL之间中间件.在后端DB看来,Atlas相当于连接它的客户端:而在前端应用看来,Atlas相当于一

高可用Hadoop平台-Oozie工作流

1.概述 在开发Hadoop的相关应用使用,在业务不复杂,任务不多的情况下,我们可以直接使用Crontab去完成相关应用的调度.今天给大家介绍的是统一管理各种调度任务的系统,下面为今天分享的内容目录: 内容介绍 Oozie Server 截图预览 下面开始今天的内容分享. 2.内容介绍 今天的内容不涉及Oozie的具体细节操作,它的工作流程在下一篇博客为大家详细介绍.今天主要给大家分享Oozie的作用,它的集成步骤等内容. 2.1 作用 Oozie它是一个开源的工作流调度系统,它可以管理逻辑复杂

高并发高可用的平台架构就一个字“拆”

根本目的是,随着用户量.数据量不断增加,系统可以通过不断的增加服务器就能解决问题,可拆的几个要点: 1.流程.通过消息组件,流程的各个节点异步交互,独立部署. 2.数据库.读写分离,多主多从.根据数据的时间.类型等等,单表的数据保存到多表.多库. 3.文件储存.通过分布式文件系统,集群存储 4.部署.通过各种的负载均衡硬件软件.域名均衡,分发到不同服务器.动静分离. 北京哪里找富婆包养鸭子 海淀区哪里找富婆包养鸭子 东城区哪里找富婆包养鸭子 西城区哪里找富婆包养鸭子 宣武区哪里找富婆包养鸭子 丰