เริ่มต้นด้วย snorql

Mar 16 2023
สถานการณ์ไม่ได้แตกต่างกันมากนักที่ Udaan เช่นกัน และนั่นคือตอนที่พวกเราบางคนตัดสินใจที่จะจัดการเรื่องต่างๆ ด้วยตัวเอง และสร้างเครื่องมือที่จะช่วยจัดการกับปัญหาเหล่านี้อย่างทันท่วงที เข้าสู่ … snorql คืออะไร? snorql เป็นโครงการโอเพ่นซอร์สที่พัฒนาขึ้นที่ Udaan โดยมีเป้าหมายเพื่อตรวจสอบและวิเคราะห์ปัญหาเกี่ยวกับฐานข้อมูลโดยใช้ SQL metrics
  • สิ่งที่คาดหวังจากโพสต์นี้?
  • รู้จักเครื่องมือของคุณ
    -
    Dropwizard
    -
    Kotlin
    -
    Maven
  • การตั้งค่าเครื่องท้องถิ่นของคุณ
  • การตั้งค่าแอปพลิเคชันของคุณ
    -
    การสร้างโครงการใหม่
    -
    การเพิ่มการอ้างอิง
    -
    สร้างและคอมไพล์
    -
    โครงสร้างโครงการ
    -
    รหัส
  • สร้างและเรียกใช้แอปพลิเคชัน
  • ขั้นตอนถัดไป
  • คำถามที่พบบ่อย

สถานการณ์ไม่ได้แตกต่างกันมากนักที่ Udaan เช่นกัน และนั่นคือตอนที่พวกเราบางคนตัดสินใจที่จะจัดการเรื่องต่างๆ ด้วยตัวเอง และสร้างเครื่องมือที่จะช่วยจัดการกับปัญหาเหล่านี้อย่างทันท่วงที

เข้า …

snorql คืออะไร?

snorql เป็นโครงการโอเพ่นซอร์สที่พัฒนาขึ้นที่ Udaan โดยมีเป้าหมายเพื่อตรวจสอบและวินิจฉัยปัญหาเกี่ยวกับฐานข้อมูลโดยใช้ SQL metrics

ให้การมองเห็นว่าทุกฐานข้อมูลทำงานอย่างไร ดังนั้นคุณจึงสามารถหยุดเล่นเกมเดาและเริ่มเพิ่มประสิทธิภาพฐานข้อมูลของคุณได้อย่างง่ายดาย และฉันจะบอกคุณว่าการมองเห็นที่เพิ่มขึ้นนี้เป็นตัวเปลี่ยนเกมสำหรับองค์กรของเรา ได้เพิ่มความรับผิดชอบของทุกทีม

ผลลัพธ์พูดสำหรับตัวเอง ขอบคุณ snorql

  • เราได้เห็นประสิทธิภาพที่เพิ่มขึ้นในฐานข้อมูลมากกว่า 50 ฐานข้อมูล
  • ลดต้นทุนคลาวด์ได้มากกว่า 60%
  • เพิ่มประสิทธิภาพการทำงานของนักพัฒนา
  • ลดเวลาในการดีบัก

หากคำนำของฉันจุดประกายความตื่นเต้นของคุณและคุณกระตือรือร้นที่จะเริ่มต้น แสดงว่าคุณมาถูกที่แล้ว แต่ในกรณีที่คุณต้องการความน่าเชื่อถือเพิ่มเติม อย่าลืมอ่านบทความที่ยอดเยี่ยมที่ชื่อว่าsnorql — การวินิจฉัยฐานข้อมูลอย่างเจ้านาย

สิ่งที่คาดหวังจากโพสต์นี้?

Snorql แสดงเมตริกหลายอย่าง เช่น Active Queries, Blocked Query, Index Stats, Database Growth และอื่นๆ… ดูรายการทั้งหมดได้ที่นี่ สำหรับโพสต์นี้ เราจะเลือกการค้นหาที่ใช้งานอยู่ Active Queries เป็นเครื่องมือที่มีค่าสำหรับผู้ใช้ SQL Server ที่ต้องการตรวจสอบและเพิ่มประสิทธิภาพการทำงานของแบบสอบถามแบบเรียลไทม์

ในโพสต์นี้ ฉันจะแสดงวิธีรวมเข้าsnorqlกับแอปพลิเคชัน Kotlin Dropwizard อย่างง่าย ( คุณสามารถทำซ้ำสิ่งเดียวกันใน Java Framework อื่น ๆ ได้เช่นกัน ) ในตอนท้ายของบทช่วยสอนนี้ แอปพลิเคชันของคุณจะแสดง RESTful API ซึ่งคุณจะสามารถค้นหาสถิติการสืบค้นแบบสดสำหรับฐานข้อมูลใดก็ตาม

รู้จักเครื่องมือของคุณ

สำหรับผู้ที่คุ้นเคยกับ Kotlin, Dropwizard และ Maven อยู่แล้ว โปรดข้ามส่วนนี้ไป

ดร็อปวิซาร์ด

Dropwizard เป็นเฟรมเวิร์ก Java แบบเบาสำหรับสร้างบริการเว็บ RESTful Dropwizard รวบรวมไลบรารีที่มีความเสถียร เช่น Jersey, Jackson และ JDBI เข้าด้วยกันเป็นแพ็คเกจที่มีน้ำหนักเบา สำหรับรายละเอียดเพิ่มเติมเยี่ยมชมhttps://www.dropwizard.io/en/latest/.

เรื่องน่ารู้: Dropwizard ได้รับแรงบันดาลใจจาก Ruby on Rails ซึ่งเป็นเฟรมเวิร์กเว็บแอปพลิเคชันยอดนิยมในภาษาโปรแกรม Ruby ผู้สร้าง Dropwizard ต้องการนำผลผลิตในระดับเดียวกันและใช้งานง่ายมาสู่ระบบนิเวศของ Java

คอตลิน

Kotlin เป็นภาษาโปรแกรมที่รองรับการเขียนโปรแกรมเชิงฟังก์ชันและเชิงวัตถุ สร้างขึ้นโดย JetBrains บริษัทพัฒนาซอฟต์แวร์ในรัสเซีย ไวยากรณ์และแนวคิดของ Kotlin คล้ายกับ C#, Scala และ Java สำหรับรายละเอียดเพิ่มเติมเยี่ยมชมhttps://kotlinlang.org/

ข้อเท็จจริงที่น่าสนุกอย่างหนึ่งเกี่ยวกับ Kotlin ก็คือชื่อของมันได้มาจากเกาะใกล้เซนต์ปีเตอร์สเบิร์ก ประเทศรัสเซีย ที่เรียกว่า Kotlin Island ผู้สร้าง Kotlin เลือกชื่อนี้เพราะหลายคนอาศัยอยู่ในหรือรอบๆ เซนต์ปีเตอร์สเบิร์ก และเกาะแห่งนี้เป็นสถานที่สำคัญที่มีชื่อเสียงในพื้นที่

มาเวน

Maven เป็นเครื่องมือสร้างอัตโนมัติและการจัดการสำหรับ Java ด้วย Maven ทำให้ง่ายต่อการกำหนดการสร้างซอฟต์แวร์และการพึ่งพา

เรื่องน่ารู้: Maven ถูกสร้างขึ้นโดย Jason van Zyl ในปี 2002 ในขณะที่เขากำลังรอเที่ยวบินที่สนามบิน O'Hare ในชิคาโก

การตั้งค่าเครื่องท้องถิ่นของคุณ

คุณจะพบบทความและวิดีโอ YouTube มากมายในแบบเดียวกัน อย่างไรก็ตาม ฉันได้แนบข้อมูลอ้างอิงสั้นๆ

  • การติดตั้งและตั้งค่า maven —https://www.freecodecamp.org/news/how-to-get-started-with-maven-36851d8cfd96/
  • การติดตั้ง Kotlin —https://www.oreilly.com/library/view/kotlin-cookbook/9781492046660/ch01.html
  • การติดตั้ง IntelliJ —https://www.jetbrains.com/help/idea/installation-guide.html

ส่วนนี้จะถือว่าคุณได้ตั้งค่า Maven, Kotlin & IntelliJ (หรือ IDE อื่น ๆ ที่รองรับโครงการ Maven) แล้ว

การสร้างโครงการใหม่

  1. คลิกที่ไฟล์ -> ใหม่ -> โครงการ -> Maven คุณจะเห็นป๊อปอัปต่อไปนี้

3. IDE ของคุณจะเปิดไฟล์ pom.xml ด้วยโปรเจ็กต์ที่มีโครงสร้างดังต่อไปนี้

การเพิ่มการพึ่งพา

ก่อนเริ่มใช้งาน เราจำเป็นต้องเพิ่มการพึ่งพาเฉพาะที่จำเป็นสำหรับโครงการในpom.xmlไฟล์ ขอทำมันด้วยกัน.

เราเริ่มต้นด้วยการกำหนดเวอร์ชันของ Kotlin & Dropwizard ในแท็กคุณสมบัติ

<properties>
	  <maven.compiler.source>8</maven.compiler.source>
	  <maven.compiler.target>8</maven.compiler.target>
	  <kotlin.version>1.4.10</kotlin.version>
	  <kotlin.compiler.languageVersion>1.4</kotlin.compiler.languageVersion>
	  <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
	  <dropwizard.version>2.0.13</dropwizard.version>
</properties>

<dependencies>
    <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-core</artifactId>
        <version>${dropwizard.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib-jdk8</artifactId>
        <version>${kotlin.version}</version>
    </dependency>
</dependencies>

jdbi3

เราต้องการการพึ่งพานี้เพื่อเชื่อมต่อกับฐานข้อมูล ฉันใช้ jdbi3 ที่นี่ ซึ่งจะใช้ได้กับ JDBC/JDBI เวอร์ชันใดก็ได้

คุณสมบัติ:

<jdbi.version>3.37.1</jdbi.version>

<dependency>
    <groupId>org.jdbi</groupId>
    <artifactId>jdbi3-core</artifactId>
    <version>${jdbi.version}</version>
</dependency>
<dependency>
    <groupId>org.jdbi</groupId>
    <artifactId>jdbi3-sqlobject</artifactId>
    <version>${jdbi.version}</version>
</dependency>
<dependency>
    <groupId>org.jdbi</groupId>
    <artifactId>jdbi3-kotlin-sqlobject</artifactId>
    <version>${jdbi.version}</version>
</dependency>

เราจะต้องเพิ่มสิ่งนี้เพื่อให้แอปพลิเคชันสามารถเชื่อมต่อกับฐานข้อมูลเซิร์ฟเวอร์ SQL ได้สำเร็จ การละเว้นสิ่งนี้จะทำให้คุณได้รับjava.sql.SQLException: No suitable driver foundข้อยกเว้น ที่น่าอับอาย ที่นี่ ฉันจะใช้snorql-extensionsโมดูลที่ให้เมตริกที่กำหนดไว้ล่วงหน้าซึ่งสอดคล้องกับเซิร์ฟเวอร์ SQL ดังนั้นเราจะไปกับไดรเวอร์นี้

มีโมดูลอื่นอยู่snorql-frameworkซึ่งเป็นเฟรมเวิร์กพื้นฐานของเครื่องมือพื้นฐาน ฉันจะสำรวจสิ่งนั้นในบทความหน้าซึ่งเราจะรู้วิธีใช้ประโยชน์จากเฟรมเวิร์กนี้สำหรับฐานข้อมูลต่างๆ เช่น Postgres, MySQL เป็นต้น...

คุณสมบัติ:

<mssql.version>9.2.1.jre8</mssql.version>

<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <version>${mssql.version}</version>
</dependency>

จะละเว้นสิ่งนี้ไม่ได้!

คุณสมบัติ:

<snorql.version>0.5.6</snorql.version>

<dependency>
    <groupId>com.udaan.snorql</groupId>
    <artifactId>snorql-extensions</artifactId>
    <version>${snorql.version}</version>
</dependency>

สร้างและคอมไพล์

ขั้นตอนต่อไปคือการระบุไดเร็กทอรีต้นทางใน<sourceDirectory>และ<testSourceDirectory>เพื่อคอมไพล์ซอร์สโค้ด เราจะกำหนดค่าปลั๊กอิน Kotlin ที่จำเป็นในการรวบรวมซอร์สโค้ดของเรา

เพิ่มรหัสpom.xmlตามที่แสดงหลังส่วนการพึ่งพา

<dependencies>
	.....
</dependencies>
<build>
    <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
    <plugins>
        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
            <version>${kotlin.version}</version>
            <executions>
                <execution>
                    <id>compile</id>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

ทันทีที่คุณทำสิ่งนี้ คุณจะเห็นkotlinถูกเน้นด้วยสีแดง นี่เป็นเพราะเส้นทางไม่มีอยู่ ณ ตอนนี้ ซึ่งนำเราไปสู่ส่วนถัดไป → โครงสร้างโครงการ

โครงสร้างโครงการ

นี่คือโครงสร้างโครงการของฉัน คุณสามารถเริ่มต้นด้วยสิ่งเดียวกันและปรับแต่งในภายหลังตามความต้องการของคุณ

รหัส

ขั้นตอนที่ 1:เราเริ่มต้นด้วยการสร้างconfig.ymlไฟล์ภายในsrc/main/resources. เราสามารถกำหนดพารามิเตอร์ในไฟล์คอนฟิกูเรชันนี้ ซึ่งจะถูกดีซีเรียลไลซ์ไปยังอินสแตนซ์ของคลาสคอนฟิกูเรชันของเรา เราจำเป็นต้องเพิ่มอย่างน้อยหนึ่งพารามิเตอร์ มิฉะนั้น Dropwizard framework จะส่งข้อผิดพลาดระหว่างการคอมไพล์ ไปข้างหน้าและเพิ่มสิ่งนี้:

environment: local

package com.hawkeye.configuration

import com.fasterxml.jackson.annotation.JsonProperty
import io.dropwizard.Configuration


class AppConfig(@JsonProperty("environment") val environment: String): Configuration()

ขั้นตอนที่ 4:ต่อไป เราสร้างBootstrapSnorqlApplicationไฟล์ .kt ภายในพาธsrc/main/kotlin/com/hawkeyeและเพิ่มโค้ดต่อไปนี้:

package com.hawkeye.core

import org.jdbi.v3.core.Jdbi
import org.jdbi.v3.core.kotlin.KotlinPlugin
import org.jdbi.v3.sqlobject.SqlObjectPlugin
import org.jdbi.v3.sqlobject.kotlin.KotlinSqlObjectPlugin

class JdbiFactory {

    /**
     * Return instance of JDBI with all plugins installed
     * @param dbName Name of the DB to connect
     */
    fun getInstance(dbName: String): Jdbi {
        return Jdbi.create(getConnectionStringByDatabaseName(dbName))
            .installPlugin(SqlObjectPlugin())
            .installPlugin(KotlinPlugin())
            .installPlugin(KotlinSqlObjectPlugin())
    }

    private fun getConnectionStringByDatabaseName(dbName: String): String {
        return when(dbName) {
            "db-prod" -> "jdbc:sqlserver://<server-name>:<port>;database=$dbName;user=<username>;password=<pwd>;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;"
            else -> ""
        }
    }
}

ขั้นตอนที่ 5:ตอนนี้เราต้องใช้Connectionอินเทอร์เฟซที่snorql-frameworkเปิดเผย เรียกมันว่าSqlServerConnection& มันจะเก็บวิธีการที่จำเป็นสำหรับsnorqlการโต้ตอบกับฐานข้อมูลของผู้ใช้ สำหรับโพสต์นี้ใช้run()วิธีการเพียงอย่างเดียวก็เพียงพอแล้ว เราจะสำรวจสิ่งอื่นๆ ในโพสต์บล็อกโดยละเอียดแยกต่างหาก

สร้างSqlServerConnection.ktไฟล์ในเส้นทางsrc/main/kotlin/com/hawkeye/coreและเพิ่มรหัสด้านล่าง

package com.hawkeye.core

import com.udaan.snorql.framework.metric.Connection
import com.udaan.snorql.framework.models.HistoricalDatabaseResult
import javax.inject.Inject

class SqlServerConnection @Inject constructor(private val jdbi3Factory: JdbiFactory) : Connection {
    override fun <T> run(databaseName:String, query: String, mapClass: Class<T>,params: Map<String, *>): List<T> {
        return if(params.isNotEmpty()){
            jdbi3Factory.getInstance(databaseName).withHandle<List<T>, Exception> { handle ->
                handle.createQuery(query).bindMap(params).mapTo(mapClass).toList()
            }
        } else{
            jdbi3Factory.getInstance(databaseName).withHandle<List<T>, Exception> { handle ->
                handle.createQuery(query).mapTo(mapClass).toList() as List<T>
            }
        }
    }

    override fun storeData(storageBucketId: String, columns: List<String>, rows: List<List<Any>>) {
        TODO("Not yet implemented")
    }

    override fun getHistoricalData(
        storageBucketId: String,
        metricId: String,
        databaseName: String,
        columns: List<String>,
        paginationParams: Map<String, *>,
        params: Map<String, *>
    ): HistoricalDatabaseResult {
        TODO("Not yet implemented")
    }
}

snorqlเปิดเผยเมตริก SQL ที่มีประโยชน์มากมายที่สามารถรวมและใช้กับแอปพลิเคชันของคุณได้ สำหรับโพสต์นี้ เราจะเลือกเมตริกที่เกี่ยวข้องมากที่สุดกับทุกคนที่เคยใช้ฐานข้อมูลActive Queries—

Active Queries หรือที่เรียกว่าสถิติคิวรีแบบสด เป็นฟีเจอร์ใน SQL Server ที่ช่วยให้ผู้ใช้สามารถติดตามความคืบหน้าของคิวรีได้แบบเรียลไทม์ ซึ่งจะให้ข้อมูลเกี่ยวกับสถานะของคิวรี เช่น เปอร์เซ็นต์ของการเสร็จสิ้น เวลาที่ผ่านไป และเวลาที่เหลือโดยประมาณ ตลอดจนแผนการดำเนินการที่ SQL Server ใช้เพื่อประมวลผลคิวรี

สร้างSnorqlMetricsResource.ktไฟล์ภายในsrc/main/kotlin/com/hawkeye/resourcesและเพิ่มรหัสด้านล่าง

package com.hawkeye.resources

import com.fasterxml.jackson.annotation.JsonProperty
import com.udaan.snorql.extensions.performance.PerformanceEnums
import com.udaan.snorql.extensions.performance.models.ActiveQueryInput
import com.udaan.snorql.extensions.performance.models.ActiveQueryResult
import com.udaan.snorql.framework.metric.SqlMetricManager
import com.udaan.snorql.framework.models.IMetricRecommendation
import com.udaan.snorql.framework.models.MetricPeriod
import javax.ws.rs.Consumes
import javax.ws.rs.POST
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.container.AsyncResponse
import javax.ws.rs.container.Suspended
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response

@Path("/snorql")
class SnorqlMetricsResource {
    /*
    * Fetches list of active-queries metric for a [activeQueryMetricInput]
    */
    @POST
    @Path("activeQueries")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    fun getActiveQueryMetric(
        input: Input,
        @Suspended asyncResponse: AsyncResponse
    ) {

        val activeQueryInput = ActiveQueryInput(
            databaseName = input.databaseName,
            metricPeriod = input.metricPeriod,
            metricId = input.metricId
        )
        try {
            val response = SqlMetricManager.getMetric<ActiveQueryInput, ActiveQueryResult, IMetricRecommendation>(
                PerformanceEnums.ACTIVE_QUERIES.getId(),
                activeQueryInput
            )
            asyncResponse.resume(Response.ok(response).build())

        } catch (e: Exception) {
            println("Something went wrong. Error : ${e.message as String}")
            Response.status(500).entity(e.message as String).build()
        }
    }
}

data class Input (
    @JsonProperty("metricId")
    val metricId: String = PerformanceEnums.ACTIVE_QUERIES.getId(),
    @JsonProperty("metricPeriod")
    val metricPeriod: MetricPeriod,
    @JsonProperty("databaseName")
    val databaseName: String
)

package com.hawkeye

import com.google.inject.AbstractModule
import com.google.inject.Guice
import com.hawkeye.configuration.AppConfig
import com.hawkeye.core.SqlServerConnection
import com.hawkeye.resources.SnorqlMetricsResource
import com.udaan.snorql.extensions.SQLCommonMetrics
import com.udaan.snorql.framework.metric.SqlMetricManager
import io.dropwizard.Application
import io.dropwizard.setup.Environment

class HawkeyeApplication: Application<AppConfig>() {
    companion object {
        @JvmStatic fun main(args: Array<String>) = HawkeyeApplication().run(*args)
    }

    override fun run(appConfig: AppConfig, environment: Environment) {
        environment.jersey().register(SnorqlMetricsResource::class.java)
        registerSQLMetrics()
    }

    private fun registerSQLMetrics() {
        val sqlServerConnectionInstance =
            Guice.createInjector(SqlClientModule()).getInstance(SqlServerConnection::class.java)
        SqlMetricManager.setConnection(sqlServerConnectionInstance)
        SQLCommonMetrics.initialize()
    }
}

class SqlClientModule : AbstractModule()

สร้างและเรียกใช้แอปพลิเคชัน

เราพร้อมที่จะดำเนินการของเราHawkeyeApplication

ในการทำเช่นนั้นให้เพิ่มการกำหนดค่าตามที่แสดงด้านล่าง:

ขอให้สังเกตว่าเราได้เพิ่มserver src/main/resources/config.ymlอาร์กิวเมนต์ของโปรแกรมเข้าไปแล้ว สิ่งนี้บอกให้แอพ Dropwizard ทำงานเป็นเซิร์ฟเวอร์และเทียบกับตำแหน่งของไฟล์การกำหนดค่าที่ให้ไว้

หากทุกอย่างเป็นไปด้วยดี คุณจะเห็นสิ่งนี้ในเทอร์มินัล หากไม่ & คุณถูกทักด้วยข้อผิดพลาด ไม่ต้องกังวล เราจัดการให้คุณแล้วเช่นกัน ไปที่ส่วนคำถามที่พบบ่อยและตรวจสอบข้อผิดพลาด/การแก้ปัญหาที่ฉันพบ

ตรงไปที่บุรุษไปรษณีย์หรือเครื่องมืออื่นที่คล้ายคลึงกันและทดสอบ API คลิกที่นำเข้า -> ข้อความดิบ -> คัดลอกวางสาย curl ที่ระบุด้านล่าง -> คลิกที่ดำเนินการต่อ -> คลิกที่ส่ง

curl --location --request POST 'localhost:8080/snorql/activeQueries' \
--header 'Content-Type: application/json' \
--data-raw '{
    "databaseName": "db-prod",
    "metricId": "performance_activeQueries",
    "metricPeriod": "REAL_TIME",
    "recommendationRequired": true
}'

ที่นี่ เราได้สอบถามเพื่อดูข้อความค้นหาที่ใช้งานอยู่ทั้งหมดสำหรับฐานdb-prodข้อมูล คำตอบแบ่งออกเป็น 3 ส่วน:

เมตริกอินพุต

ซึ่งจะส่งคืนอินพุตที่ผู้ใช้ให้ไว้พร้อมค่าเริ่มต้นในช่องตัวเลือก

"metricInput": {
    "from": null,
    "to": null,
    "recommendationRequired": false,
    "metricId": "performance_activeQueries",
    "metricPeriod": "REAL_TIME",
    "databaseName": "db-prod"
  }

ซึ่งจะแสดงรายการของข้อความค้นหาที่กำลังทำงานอยู่ในขณะนี้ในฐานข้อมูลของคุณพร้อมกับพารามิเตอร์ที่เกี่ยวข้องทั้งหมดที่เกี่ยวข้อง สิ่งนี้อาจมีประโยชน์ในสถานการณ์ต่อไปนี้:

  • เมื่อคุณพยายามดีบักเวลาแฝงที่เพิ่มขึ้นในฐานข้อมูลของคุณ & คุณต้องการตรวจสอบว่ามีการสืบค้นที่ใช้เวลานานซึ่งทำให้ CPU ของคุณทำงานเกินกำลังหรือไม่โดยดูelapsedTimeที่ ข้อความค้นหาที่ใช้เวลานานเหล่านี้อาจเกิดจากปัญหาต่างๆ เช่น แผนการสืบค้นที่ไม่มีประสิทธิภาพ การจัดทำดัชนีที่ไม่เหมาะสม หรือข้อความค้นหาที่เขียนไม่ดี นอกจากนี้ เรายังสามารถใช้ข้อมูลนี้เพื่อวิเคราะห์การกระจายของเวลาการดำเนินการสืบค้นทั่วทั้งฐานข้อมูล และดำเนินการเชิงรุกเพื่อป้องกันปัญหาก่อนที่จะเกิดขึ้น
  • เมื่อคุณอยู่ในสถานะที่ฐานข้อมูลหยุดทำงานหรือกระบวนการไม่ดำเนินการ การตรวจสอบการบล็อกฐานข้อมูลนั้นสมเหตุสมผลมาก & คุณสามารถหาค่า sessionId ที่แน่นอนที่บล็อกการสืบค้นนี้ได้ด้วยความช่วยเหลือblockedByของ
  • พารามิเตอร์ นี้openTransactionCountใช้เพื่อตรวจสอบจำนวนธุรกรรมที่เปิดอยู่ในฐานข้อมูล ณ เวลาใดก็ตาม หากจำนวนนี้สูงอย่างต่อเนื่อง อาจบ่งชี้ว่ามีธุรกรรมที่ไม่ได้ดำเนินการหรือย้อนกลับในเวลาที่เหมาะสม ซึ่งอาจนำไปสู่ปัญหาต่างๆ เช่น การแย่งชิงทรัพยากร การล็อกที่เพิ่มขึ้น และการล็อกตาย ซึ่งอาจส่งผลเสียต่อประสิทธิภาพและความพร้อมใช้งานของฐานข้อมูล ด้วยการใช้openTransactionCountพารามิเตอร์ร่วมกับเมตริกประสิทธิภาพอื่นๆ เช่น เวลาการดำเนินการค้นหาและเวลารอการค้นหา เราจึงสามารถระบุการค้นหาที่ต้องการความสนใจได้อย่างถูกต้อง

"metricOutput": {
    "result": {
	"queryList": [
	    {
		"sessionId": 627,
		"status": "running",
		"blockedBy": 0,
		"waitType": null,
		"waitResource": "",
		"percentComplete": 0,
		"waitTime": "00:00:00",
		"cpuTime": 2,
		"logicalReads": 19,
		"reads": 0,
		"writes": 0,
		"elapsedTime": "0d 00:00:00",
		"queryText": "<?query --  \\n\\nSELECT DISTINCT ffi.shipment_group_id, so.extra_data, so.order_type, cac.amount_in_paisa as consumed_amount_in_paisa FROM fulfillment_line_items ffi JOIN seller_order_line ol on ol.order_line_id = ffi.order_line_id JOIN seller_order so on so.order_id = ol.seller_order_id LEFT OUTER JOIN collected_advance_consumable cac on cac.consumed_for = ffi.shipment_group_id WHERE ffi.shipment_group_id in (@P0)\\n\\n--?>",
		"storedProc": "",
		"command": "SELECT",
		"loginName": "udaan",
		"hostName": "order-processing-daemons-6fdfb74677-86xtx",
		"programName": "order-processing-daemons-6fdfb74677-86xtx/order-mgmt",
		"hostProcessId": 0,
		"lastRequestEndTime": "2023-02-24 10:36:18.283",
		"loginTime": "2023-02-24 10:32:52.12",
		"openTransactionCount": 0
	     }
	 ]
    },
    "recommendation": null
}

ส่วนนี้ให้รายละเอียดเกี่ยวกับการสืบค้นที่ snorql ใช้เพื่อสร้างผลลัพธ์ข้างต้น นอกจากนี้ยังมาพร้อมกับคำอธิบายสั้น ๆ และการอ้างอิงอย่างรวดเร็วไปยังเอกสารอย่างเป็นทางการของ Microsoft

& เป็นส่วนหนึ่งของคุณสมบัติที่ snorql ช่วยเราในการบันทึกและจัดเก็บชุดผลลัพธ์ของเอาต์พุตการสืบค้นในช่วงเวลาที่กำหนด ซึ่งช่วยให้เราสามารถย้อนกลับไปดูข้อมูลที่ผ่านมาsupportsHistoricalได้ minimumRepeatIntervalซึ่งจะช่วยในการชันสูตรพลิกศพ ระบุปัญหา และค้นหาความผิดปกติ ฟีเจอร์นี้ต้องการโพสต์ที่มีรายละเอียดแยกเป็นของตนเอง

"metadata": {
    "underlyingQueries": [
        "SELECT sessionId=s.session_id\\n ,status=r.STATUS\\n ,blockedBy=r.blocking_session_id\\n ,waitType=r.wait_type\\n, waitResource=r.wait_resource\\n, waitTime=CONVERT(VARCHAR, DATEADD(ms, r.wait_time, 0), 8)\\n, cpuTime=r.cpu_time\\n, logicalReads=r.logical_reads\\n, r.reads\\n ,r.writes,\\n r.percent_complete as percentComplete\\n,elapsedTime=CONVERT(varchar, (r.total_elapsed_time/1000 / 86400))+ 'd ' +\\n CONVERT(VARCHAR, DATEADD(ms, r.total_elapsed_time, 0), 8)\\n ,queryText=CAST((\\n         '<?query --  ' + CHAR(13) + CHAR(13) + Substring(st.TEXT, (r.statement_start_offset / 2) + 1, (\\n  (\\n CASE r.statement_end_offset\\n WHEN - 1\\n THEN Datalength(st.TEXT)\\n  ELSE r.statement_end_offset\\n END - r.statement_start_offset\\n) / 2\\n) + 1) + CHAR(13) + CHAR(13) + '--?>'\\n ) AS XML)\\n, storedProc=COALESCE(\\n QUOTENAME(DB_NAME(st.dbid)) + N'.' + \\n QUOTENAME(OBJECT_SCHEMA_NAME(st.objectid, st.dbid)) + N'.' +\\n QUOTENAME(OBJECT_NAME(st.objectid, st.dbid)), ''\\n)\\n  --,qp.query_plan AS 'xml_plan'  -- uncomment (1) if you want to see plan\\n, r.command\\n ,loginName=s.login_name\\n ,hostName=s.host_name\\n ,programName=s.program_name\\n ,hostProcessId=s.host_process_id\\n ,lastRequestEndTime=s.last_request_end_time\\n ,loginTime=s.login_time\\n ,openTransactionCount=r.open_transaction_count\\n FROM sys.dm_exec_sessions AS s\\n INNER JOIN sys.dm_exec_requests AS r ON r.session_id = s.session_id\\n CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS st\\n --OUTER APPLY sys.dm_exec_query_plan(r.plan_handle) AS qp -- uncomment (2) if you want to see plan \\n ORDER BY r.blocking_session_id"
    ],
    "referenceDocumentation": [],
    "description": "",
    "supportsHistorical": true,
    "minimumRepeatInterval": "10"
}

หากคุณต้องการตรวจสอบรหัสทั้งหมด เยี่ยมชมที่นี่ที่https://github.com/lakshmi-udaan/hawkeye

ขั้นตอนถัดไป

เราทำอะไร?

เมื่อได้รับข้อมูลที่จำเป็นแล้ว เราจึงเริ่มสร้างเครื่องมือสร้างภาพที่มีประสิทธิภาพ เพื่อจุดประสงค์นี้ เราได้เสริม APIs ด้วยเลเยอร์ UI ที่เป็นมิตรกับผู้ใช้และสร้างแดชบอร์ด SQL ซึ่งให้ทั้งมุมมองมุมสูงที่ครอบคลุมของฐานข้อมูลทั้งหมดและมุมมองแบบละเอียดของแต่ละฐานข้อมูล นักพัฒนาขององค์กรของเราพึ่งพาสิ่งนี้อย่างมากสำหรับงานที่เกี่ยวข้องกับ SQL น่าเสียดายที่ขณะนี้ยังไม่ใช่โอเพ่นซอร์ส แต่ถ้าคุณสนใจ เรายินดีที่จะพูดคุยเพิ่มเติม นี่คือจุดสูงสุดของสิ่งเดียวกัน

แดชบอร์ดการวินิจฉัยและการตรวจสอบ SQL ที่ udaan สร้างขึ้นโดยใช้ snorql

คุณสามารถทำอะไรได้บ้าง?

ตอนนี้คุณรู้วิธีใช้ snorql แล้ว ก็เหลือเวลาอีกไม่มากก่อนที่คุณจะปลดล็อกศักยภาพทั้งหมดและเริ่มเพิ่มประสิทธิภาพฐานข้อมูลของคุณแบบทวีคูณ

คุณสามารถดูรายการเมตริกที่มีทั้งหมดได้ที่นี่ คุณสามารถรับเมตริกเหล่านี้ได้โดยแก้ไขพารามิเตอร์ที่ส่งผ่านภายในSqlMetricManager.getMetric()เหมือนที่เราทำในขณะที่สร้างตำแหน่งข้อมูล API สำหรับการสืบค้นที่ใช้งานที่นี่

ในโพสต์ถัดไป เราจะลงลึกถึงวิธีที่เราสามารถใช้เมตริกเหล่านี้เพื่อเพิ่มประสิทธิภาพการทำงานของฐานข้อมูลได้ถึง 10 เท่า

ขอบคุณที่อ่าน!

คำถามที่พบบ่อย

  • ไม่พบสิ่งประดิษฐ์ com.udaan.snorql:snorql-framework:pom:0.5.6 ใน xyz
    วิธีแก้ไข: ทำไฟล์mvn clean install. สิ่งนี้จะล้างสิ่งที่สร้างขึ้นจากบิลด์ก่อนหน้า จากนั้นสร้างโปรเจ็กต์ของคุณและเพิ่ม jar ลงในที่เก็บ maven ในเครื่องของคุณ (.m2\repository)
  • หากคุณได้รับแจ้งพร้อมข้อผิดพลาดนี้ วิธีแก้ไข: คุณต้องโหลด. คุณพลาดการเพิ่มjava.sql.SQLException: No suitable driver found
    jdbc drivermssql-jdbc

https://udaan-com.github.io/snorql/

https:///engineering-udaan/snorql-diagnosing-databases-like-a-boss-54f2e8fbf57a