HDInsight üzerinde Apache Spark kümesiyle özel bir Python kitaplığı kullanarak web sitesi günlüklerini analiz etme

Bu not defteri, HDInsight üzerinde Apache Spark ile özel bir kitaplık kullanarak günlük verilerini çözümlemeyi gösterir. Kullandığımız özel kitaplık, iislogparser.py adlı bir Python kitaplığıdır.

Önkoşullar

HDInsight üzerinde bir Apache Spark kümesi. Yönergeler için bkz. Azure HDInsight'ta Apache Spark kümeleri oluşturma.

Ham verileri RDD olarak kaydetme

Bu bölümde, ham örnek verilerinizi işleyen işleri çalıştırmak ve hive tablosu olarak kaydetmek için HDInsight'ta Apache Spark kümesiyle ilişkili Jupyter Not Defteri'ni kullanacağız. Örnek veriler, varsayılan olarak tüm kümelerde kullanılabilen bir .csv dosyasıdır (hvac.csv).

Verileriniz Apache Hive tablosu olarak kaydedildikten sonra, sonraki bölümde Power BI ve Tableau gibi BI araçlarını kullanarak Hive tablosuna bağlanacağız.

  1. Bir web tarayıcısından adresine gidin https://CLUSTERNAME.azurehdinsight.net/jupyter; burada CLUSTERNAME kümenizin adıdır.

  2. Yeni bir not defteri oluşturun. Yeni'yi ve ardından PySpark'ı seçin.

    Create a new Apache Jupyter Notebook. Not defteri" border="true":::

  3. Yeni bir not defteri oluşturulur ve Untitled.pynb adı ile açılır. Üst kısımdaki not defteri adını seçin ve kolay bir ad girin.

    Provide a name for the notebook.

  4. PySpark çekirdeğini kullanarak bir not defteri oluşturduğunuz için açıkça bağlam oluşturmanız gerekmez. Birinci kod hücresini çalıştırdığınızda Spark ve Hive bağlamları sizin için otomatik olarak oluşturulur. Bu senaryo için gerekli türleri içeri aktararak başlayabilirsiniz. Aşağıdaki kod parçacığını boş bir hücreye yapıştırın ve shift + Enter tuşlarına basın.

    from pyspark.sql import Row
    from pyspark.sql.types import *
    
  5. Kümede zaten kullanılabilir olan örnek günlük verilerini kullanarak bir RDD oluşturun. verilerine adresinden kümeyle \HdiSamples\HdiSamples\WebsiteLogSampleData\SampleLog\909f2b.logilişkili varsayılan depolama hesabından erişebilirsiniz. Şu kodu yürütün:

    logs = sc.textFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b.log')
    
  6. Önceki adımın başarıyla tamamlandığını doğrulamak için örnek bir günlük kümesi alın.

    logs.take(5)
    

    Aşağıdaki metne benzer bir çıkış görmeniz gerekir:

    [u'#Software: Microsoft Internet Information Services 8.0',
    u'#Fields: date time s-sitename cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Cookie) cs(Referer) cs-host sc-status sc-substatus sc-win32-status sc-bytes cs-bytes time-taken',
    u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step2.png X-ARR-LOG-ID=2ec4b8ad-3cf0-4442-93ab-837317ece6a1 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 53175 871 46',
    u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step3.png X-ARR-LOG-ID=9eace870-2f49-4efd-b204-0d170da46b4a 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 51237 871 32',
    u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step4.png X-ARR-LOG-ID=4bea5b3d-8ac9-46c9-9b8c-ec3e9500cbea 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 72177 871 47']
    

Özel Python kitaplığı kullanarak günlük verilerini analiz etme

  1. Yukarıdaki çıktıda, ilk çift satırlar üst bilgi bilgilerini içerir ve kalan her satır bu üst bilgide açıklanan şemayla eşleşir. Bu tür günlükleri ayrıştırma karmaşık olabilir. Bu nedenle, bu tür günlükleri ayrıştırmanızı çok daha kolay hale getiren özel bir Python kitaplığı (iislogparser.py) kullanırız. Varsayılan olarak, bu kitaplık konumunda HDInsight /HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.pyüzerinde Spark kümenize dahil edilir.

    Ancak, bu kitaplık içinde PYTHONPATH olmadığından gibi import iislogparserbir içeri aktarma deyimi kullanarak bu kitaplığı kullanamayız. Bu kitaplığı kullanmak için tüm çalışan düğümlerine dağıtmamız gerekir. Aşağıdaki kod parçacığını çalıştırın.

    sc.addPyFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py')
    
  2. iislogparserbir günlük satırı üst bilgi satırıysa döndüren None ve bir günlük satırıyla karşılaşırsa sınıfın LogLine bir örneğini döndüren bir işlev parse_log_line sağlar. RDD'den LogLine yalnızca günlük satırlarını ayıklamak için sınıfını kullanın:

    def parse_line(l):
        import iislogparser
        return iislogparser.parse_log_line(l)
    logLines = logs.map(parse_line).filter(lambda p: p is not None).cache()
    
  3. Adımın başarıyla tamamlandığını doğrulamak için ayıklanan birkaç günlük satırı alın.

    logLines.take(2)
    

    Çıktı aşağıdaki metne benzer olmalıdır:

    [2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step2.png X-ARR-LOG-ID=2ec4b8ad-3cf0-4442-93ab-837317ece6a1 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 53175 871 46,
    2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step3.png X-ARR-LOG-ID=9eace870-2f49-4efd-b204-0d170da46b4a 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 51237 871 32]
    
  4. Sınıfı LogLine da, bir günlük girişinin hata kodu olup olmadığını döndüren gibi is_error()bazı yararlı yöntemlere sahiptir. Ayıklanan günlük satırlarındaki hataların sayısını hesaplamak ve ardından tüm hataları farklı bir dosyaya kaydetmek için bu sınıfı kullanın.

    errors = logLines.filter(lambda p: p.is_error())
    numLines = logLines.count()
    numErrors = errors.count()
    print 'There are', numErrors, 'errors and', numLines, 'log entries'
    errors.map(lambda p: str(p)).saveAsTextFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b-2.log')
    

    Çıkış durumu There are 30 errors and 646 log entriesolmalıdır.

  5. Matplotlib kullanarak verilerin görselleştirmesini de oluşturabilirsiniz. Örneğin, uzun süre çalışan isteklerin nedenini yalıtmak istiyorsanız, ortalama olarak hizmet vermek için en çok zaman alan dosyaları bulmak isteyebilirsiniz. Aşağıdaki kod parçacığı, bir isteğe hizmet vermek için en çok zaman alan ilk 25 kaynağı alır.

    def avgTimeTakenByKey(rdd):
        return rdd.combineByKey(lambda line: (line.time_taken, 1),
                                lambda x, line: (x[0] + line.time_taken, x[1] + 1),
                                lambda x, y: (x[0] + y[0], x[1] + y[1]))\
                    .map(lambda x: (x[0], float(x[1][0]) / float(x[1][1])))
    
    avgTimeTakenByKey(logLines.map(lambda p: (p.cs_uri_stem, p))).top(25, lambda x: x[1])
    

    Aşağıdaki metne benzer bir çıktı görmeniz gerekir:

    [(u'/blogposts/mvc4/step13.png', 197.5),
    (u'/blogposts/mvc2/step10.jpg', 179.5),
    (u'/blogposts/extractusercontrol/step5.png', 170.0),
    (u'/blogposts/mvc4/step8.png', 159.0),
    (u'/blogposts/mvcrouting/step22.jpg', 155.0),
    (u'/blogposts/mvcrouting/step3.jpg', 152.0),
    (u'/blogposts/linqsproc1/step16.jpg', 138.75),
    (u'/blogposts/linqsproc1/step26.jpg', 137.33333333333334),
    (u'/blogposts/vs2008javascript/step10.jpg', 127.0),
    (u'/blogposts/nested/step2.jpg', 126.0),
    (u'/blogposts/adminpack/step1.png', 124.0),
    (u'/BlogPosts/datalistpaging/step2.png', 118.0),
    (u'/blogposts/mvc4/step35.png', 117.0),
    (u'/blogposts/mvcrouting/step2.jpg', 116.5),
    (u'/blogposts/aboutme/basketball.jpg', 109.0),
    (u'/blogposts/anonymoustypes/step11.jpg', 109.0),
    (u'/blogposts/mvc4/step12.png', 106.0),
    (u'/blogposts/linq8/step0.jpg', 105.5),
    (u'/blogposts/mvc2/step18.jpg', 104.0),
    (u'/blogposts/mvc2/step11.jpg', 104.0),
    (u'/blogposts/mvcrouting/step1.jpg', 104.0),
    (u'/blogposts/extractusercontrol/step1.png', 103.0),
    (u'/blogposts/sqlvideos/sqlvideos.jpg', 102.0),
    (u'/blogposts/mvcrouting/step21.jpg', 101.0),
    (u'/blogposts/mvc4/step1.png', 98.0)]
    
  6. Bu bilgileri çizim biçiminde de sunabilirsiniz. Çizim oluşturmanın ilk adımı olarak, önce geçici bir AverageTime tablosu oluşturalım. Tablo, belirli bir zamanda olağan dışı gecikme süresi artışları olup olmadığını görmek için günlükleri zamana göre gruplandırır.

    avgTimeTakenByMinute = avgTimeTakenByKey(logLines.map(lambda p: (p.datetime.minute, p))).sortByKey()
    schema = StructType([StructField('Minutes', IntegerType(), True),
                        StructField('Time', FloatType(), True)])
    
    avgTimeTakenByMinuteDF = sqlContext.createDataFrame(avgTimeTakenByMinute, schema)
    avgTimeTakenByMinuteDF.registerTempTable('AverageTime')
    
  7. Ardından AverageTime tablosundaki tüm kayıtları almak için aşağıdaki SQL sorgusunu çalıştırabilirsiniz.

    %%sql -o averagetime
    SELECT * FROM AverageTime
    

    Ardından %%sql gelen büyü -o averagetime , sorgunun çıkışının Jupyter sunucusunda (genellikle küme baş düğümü) yerel olarak kalıcı olmasını sağlar. Çıkış, belirtilen averagetime adlı bir Pandas veri çerçevesi olarak kalıcı hale geldi.

    Aşağıdaki görüntüye benzer bir çıkış görmeniz gerekir:

    hdinsight jupyter sql query output. yter sql query output" border="true":::

    Büyü hakkında %%sql daha fazla bilgi için bkz . %%sql magic ile desteklenen parametreler.

  8. Artık verilerin görselleştirmesini oluşturmak için kullanılan bir kitaplık olan Matplotlib'i kullanarak çizim oluşturabilirsiniz. Çizimin yerel olarak kalıcı averagetime veri çerçevesinden oluşturulması gerektiğinden, kod parçacığı sihirle %%local başlamalıdır. Bu, kodun Jupyter sunucusunda yerel olarak çalıştırılmasını sağlar.

    %%local
    %matplotlib inline
    import matplotlib.pyplot as plt
    
    plt.plot(averagetime['Minutes'], averagetime['Time'], marker='o', linestyle='--')
    plt.xlabel('Time (min)')
    plt.ylabel('Average time taken for request (ms)')
    

    Aşağıdaki görüntüye benzer bir çıkış görmeniz gerekir:

    apache spark web log analysis plot. eb log analysis plot" border="true":::

  9. Uygulamayı çalıştırmayı bitirdikten sonra, kaynakları serbest bırakmak için not defterini kapatmanız gerekir. Bunu yapmak için not defterindeki Dosya menüsünde Kapat ve Durdur’u seçin. Bu eylem not defterini kapatır ve kapatır.

Sonraki adımlar

Aşağıdaki makaleleri inceleyin: