Redis এবং পারফরম্যান্স API-এর জন্য Upstash-এর এই নিবন্ধে, আমরা দেখব কিভাবে আপনি Deno অ্যাপে Redis-এর জন্য Upstash ব্যবহার করতে পারেন। Redis এর জন্য Upstash সার্ভার-সাইড ক্যাশিং এর জন্য একটি সার্ভারহীন ডাটাবেস আদর্শ . আমি যে ওয়েব অ্যাপে কাজ করছিলাম সেটি প্রাথমিক সার্ভার রেসপন্স টাইমে খারাপ স্কোর করছে . Lighthouse রিপোর্ট করছিল 500 ms . একটি Upstash ক্যাশে যোগ করে আমি এটিকে 150 ms এর নিচে নিয়ে এসেছি এবং অডিট পাস. কঠিন অংশ ক্যাশে যোগ করা হয় নি; যেমনটি ঘটে, ক্যাশে কোথায় ব্যবহার করতে হবে তা নির্ধারণ করা গুরুত্বপূর্ণ ছিল। শুধুমাত্র কর্মক্ষমতা পরিমাপ করে আমি অবস্থিত শনাক্ত করতে পেরেছি ন্যূনতম কাজের সাথে কর্মক্ষমতা বাড়াতে। আমরা এই নিবন্ধে কর্মক্ষমতা পরিমাপ একটি ঘনিষ্ঠভাবে দেখুন.
আমার প্রকল্প ছিল একটি ডেনো ফ্রেশ ওয়েব অ্যাপ। Deno তাত্ক্ষণিক বিল্ড এবং স্থাপন আছে. এটি অপ্টিমাইজেশানের জন্য কাজ করার জন্য এটিকে একটি স্বপ্নের পরিবেশ করে তোলে। প্রতিক্রিয়া লুপ ছোট. আপনি স্থানীয়ভাবে একটি অপ্টিমাইজেশান কোড আপ করতে পারেন, এটি সার্ভারে ঠেলে দিতে পারেন এবং তাৎক্ষণিকভাবে দূরবর্তী সাইটটি পরীক্ষা করতে সক্ষম হন৷
স্ট্যাক
এখানে, আমি একটি কঙ্কাল অ্যাপ ব্যবহার করে কর্মক্ষমতা উন্নত করার বিষয়ে কথা বলব। এটি নিম্নলিখিত টুলিং ব্যবহার করে:
upstash_redis:Redis
-এর জন্য Upstash-এর সাথে কাজ করার জন্য একটি Deno মডিউল - ডেনো ফ্রেশ:Deno-এ সার্ভার-সাইড রেন্ডারড (SSR) অ্যাপ তৈরির জন্য একটি নতুন, উৎপাদন-প্রস্তুত ফ্রেমওয়ার্ক
- সার্ভারহীন লগিং:আমরা এখানে কনসোল ব্যবহার করি, কিন্তু আপনার নিয়োজিত অ্যাপের জন্য, লাইভ পরিমাপ অ্যাক্সেস করতে আপনার লগটেলের মতো একটি পরিষেবার প্রয়োজন হবে
সেটআপ
নোড এবং ডেনোর মধ্যে একটি মূল পার্থক্য হল আপনি কীভাবে আপনার কোডে তৃতীয় পক্ষের মডিউলগুলি অ্যাক্সেস করেন। Deno URL-এর সাথে কাজ করে এবং package.json এর পরিবর্তে মানচিত্র আমদানি করে ফাইল upstash_redis এর জন্য সম্পূর্ণ URL , উদাহরণস্বরূপ, হল https://deno.land/x/upstash_redis@v1.20.0 . শুরু করতে একটি নতুন Deno Fresh অ্যাপ তৈরি করুন।
deno run -A -r https://fresh.deno.dev upstash-redis-deno-perf আপনি কিছু টার্মিনাল কমান্ড দিয়ে আপনার সিস্টেমে Deno নিজেই সেট আপ করতে পারেন, যদি আপনি এটি প্রথমবার চেষ্টা করছেন।
এখন আপনি import_map.json-এ Upstash যোগ করতে পারেন প্রোজেক্ট রুট ডিরেক্টরিতে:
{
"imports": {
"@/": "./",
"$fresh/": "https://deno.land/x/fresh@1.1.2/",
// ...TRUNCATED
"$std/": "https://deno.land/std@0.177.0/",
"upstash/": "https://deno.land/x/upstash_redis@v1.20.0/"
}
} @/সুবিধার জন্য একটি আমদানি উপনাম সংজ্ঞায়িত করে। এটি আপনাকেcomponentsআমদানি করতে দেয় (প্রজেক্ট রুট ডিরেক্টরিতে)@/componentsব্যবহার করে আপনার সোর্স ফাইল কোন ফোল্ডারে থাকুক না কেন।$std/ডেনো স্ট্যান্ডার্ড লাইব্রেরির জন্য আমাদের উপনাম যার.envপড়ার জন্য একটি ইউটিলিটি ফাংশন রয়েছে পরিবেশ পরিবর্তনশীল ফাইল।upstash/প্রজেক্টের যেকোনো TypeScript বা JavaScript সোর্স ফাইল থেকে Redis লাইব্রেরির জন্য Upstash অ্যাক্সেস করতে দেয়।
Redis এবং পারফরম্যান্স API এর জন্য Upstash:Skeleton App
কঙ্কাল অ্যাপটি টানবে:
- টিনিবার্ড (সার্ভারবিহীন ক্লিকহাউস) থেকে ওয়েব বিশ্লেষণ ব্যবহার করে গত ২৮ দিনে পৃষ্ঠা দেখা
- ওয়েবমেন্টেশন ব্যবহার করে পৃষ্ঠা লাইক
আমাদের সার্ভারের কাজগুলিকে বাস্তব-বিশ্বের ব্যবসায়িক অ্যাপের মোটামুটি প্রতিনিধিত্ব করে আনার অনুরোধগুলি ব্যবহার করে এই ডেটাগুলি সংগ্রহ করা হয়। likes এবং views ভেরিয়েবল এই দুটি API থেকে প্রতিক্রিয়া ধারণ করে যা আমরা ফ্রন্টএন্ডে প্রদর্শন করি।

সার্ভার handler সেই পৃষ্ঠার কোড দেখতে এইরকম কিছু দেখায়:
export const handler: Handlers<Data> = {
async GET(request, context) {
const { url } = request;
const { pathname } = new URL(url);
const likes = await getWebmentionLikes(pathname);
const views = await getTinybirdViews({ days: 28 });
return context.render({ likes, views });
},
};
আমরা pathname বের করি ইনকামিং request থেকে অবজেক্ট, তারপর pathname ব্যবহার করুন ডেটা হেল্পার ফাংশনে এবং পরিশেষে, রিমোটলি সোর্স করা মানগুলি ফেরত দিন৷
দক্ষতার জন্য, সাহায্যকারী ফাংশনগুলিতে কলগুলি পুনর্গঠন করা যেতে পারে:
const [likes, views] = await Promise.all([
getWebmentionLikes(pathname),
getTinybirdViews({ days: 28 }),
]); জাভাস্ক্রিপ্ট পারফরম্যান্স ওয়েব API
কর্মক্ষমতা পরিমাপ সাধারণত অপ্টিমাইজেশানের প্রথম ধাপ হওয়া উচিত। হার সীমিত করার পদক্ষেপটি সর্বদা আপনি যা আশা করেন তা নয়। পরিমাপ না করে, আপনি সহজেই সময় এবং সংস্থান ব্যয় করতে পারেন যা একটি সাবঅপ্টিমাল সমাধান হতে পারে। পারফরম্যান্স API এখানে শেষ করতে সাহায্য করতে পারে। এই বিভাগে আমরা দেখি যে অ্যাপে Redis-এর জন্য Upstash ব্যবহার করা কোথায় সবচেয়ে বেশি অর্থপূর্ণ তা নির্ধারণ করতে আমরা কীভাবে এটি ব্যবহার করতে পারি।
window.performance ক্লায়েন্ট ব্রাউজার থেকে আপনাকে পারফরম্যান্স ওয়েব API-এ অ্যাক্সেস দেয়। Deno সার্ভারে ওয়েব API ব্যবহার করে এবং তাই performance সমর্থন করে আপনার ডেনো সার্ভার-সাইড কোডে বিশ্বব্যাপী উপলব্ধ। এখানে দুটি কর্মক্ষমতা পদ্ধতি রয়েছে যা আপনি ব্যবহার করতে চান:
performance.mark('your-mark-name'):একটিPerformanceMarkতৈরি করে বস্তু, যা সময়ের একটি বিন্দু প্রতিনিধিত্ব করে। আপনি যখন চিহ্ন দিয়ে একটি পরিমাপ তৈরি করেন তখন নামের প্যারামিটারটি ব্যবহার করা হয়।performance.measure('your description', startMarkName, finishMarkName):একটিPerformanceMeasureতৈরি করে বস্তু এটি একটি লেবেলের সাথে শুরু এবং সমাপ্তির সময় চিহ্নগুলিকে সংযুক্ত করে, লগিং করার জন্য এবং ইভেন্টটি চালানোর জন্য কত সময় লেগেছিল তা হিসাব করার জন্য দরকারী৷
timeEvent :পারফরম্যান্স হেল্পার ফাংশন
এখন যেহেতু আমরা মৌলিক বিষয়গুলি জানি, আসুন একটি timeEvent তৈরি করি ফাংশন এটি PerformanceMeasure এর একটি অ্যারে নেবে৷ বস্তু এবং একটি ফাংশন আমরা ইনপুট হিসাবে সময় করতে চাই. timeEvent একটি স্টার্ট মার্ক তৈরি করবে, পাস করা ফাংশনকে আহ্বান করবে, তারপর অবিলম্বে একটি ফিনিশ মার্ক তৈরি করবে। অবশেষে, এটি PerformanceMeasure এর অ্যারেকে পরিবর্তন করবে এটি ইনপুট হিসাবে প্রাপ্ত বস্তু, নতুন যোগ করে। এখানে utils/performance.ts থেকে কোড আছে :
export async function timeEvent<EventReturnType>(
eventFunction: () => Promise<EventReturnType>,
{
description,
performanceMeasures,
}: { description: string; performanceMeasures: PerformanceMeasure[] },
): Promise<EventReturnType> {
// prepare
const startName = `${description}-started`;
const finishName = `${description}-finished`;
// time
performance.mark(startName);
const result = await eventFunction();
performance.mark(finishName);
// record
performanceMeasures.push(
performance.measure(description, startName, finishName),
);
return result;
}
ফাংশনটি জেনেরিক, যদিও কঙ্কাল অ্যাপের জন্য, EventReturnType সর্বদা একটি সংখ্যা হবে৷
পরিমাপ সহ সার্ভার কোড আপডেট করা হচ্ছে
আমরা নতুন timeEvent ব্যবহার করতে পারি হ্যান্ডলারে ফাংশন, তারপর তুলনা চালানো শুরু করুন। এখানে আপডেট করা সার্ভার হ্যান্ডলার কোড আছে:
import type { Handlers, PageProps } from "$fresh/server.ts";
import "$std/dotenv/load.ts"; /* included for visibility here, typically you
can import once for project in `dev.ts` */
import { timeEvent } from "@/utils/performance.ts";
// ...TRUNCATED
export const handler: Handlers<Data> = {
async GET(request, context) {
// ...TRUNCATED
const performanceMeasures: PerformanceMeasure[] = [];
const [likes, views] = await Promise.all([
timeEvent<number>(() => getWebmentionLikes(pathname), {
description: "web-mention-likes",
performanceMeasures,
}),
timeEvent<number>(() => getTinybirdViews({ days: 28 }), {
description: "analytics-views",
performanceMeasures,
}),
]);
// Replace with a serverless logging service for production
console.log({ performanceMeasures });
return context.render({ likes, views });
},
};
timeEvent ফাংশনটি ফাংশনের ফলাফল প্রদান করে যা আমরা এতে পাস করি। এই প্রপার্টিটি আমাদের আগে timeEvent এ দুটি ডেটা হেল্পার ফাংশন গুটিয়ে নিতে দেয় কল আমরা এখানে স্থানীয়ভাবে চালাচ্ছি। একটি প্রোডাকশন অ্যাপের জন্য, আপনাকে আপনার লাইভ সাইটে পরিমাপ চালাতে হবে, যেহেতু আপনার সার্ভারে ব্যাকবোন সংযোগগুলি স্থানীয়দের থেকে আলাদাভাবে কাজ করবে। সার্ভারে চলাকালীন ব্যবস্থাগুলি রেকর্ড করতে Logtail এর মতো একটি লগিং পরিষেবা ব্যবহার করুন৷

কনসোল লগের ক্যাপচারে, আপনি PerformanceMeasure দেখতে পারেন অবজেক্ট নিম্নলিখিত পরিমাপ মান প্রদান করে (যা আমরা আগে উল্লেখ করেছি):
- নাম
- শুরু করার সময়
- সময়কাল (মিলিসেকেন্ডে)
আদর্শভাবে, অ্যাপটি রেন্ডার করার জন্য আমাদের উভয় ডেটা মান (লাইক এবং ভিউ) প্রয়োজন। এখানে তারা একে অপরের সমান সময় নিয়েছে (২ সেকেন্ড)। যদি একটি ফাংশন অন্যটির তুলনায় অনেক ধীর গতিতে চলত, তাহলে আমরা ধীরগতির মানের জন্য Redis ক্যাশিংয়ের জন্য Upstash যোগ করব। পরিবর্তে, এখানে আমরা এটি উভয়ের সাথে যোগ করব। দ্রষ্টব্য, উত্পাদনে, আমরা কমপক্ষে কয়েকশ ডেটা পয়েন্ট চাই। তারপরে আমরা তুলনা করার জন্য গড় বা P90 এর মতো একটি সামগ্রিক পরিমাপ ব্যবহার করতে পারি।
Analytics হেল্পার কোডে Redis-এর জন্য Upstash যোগ করা
আসুন বিশ্লেষণ সহায়ক ফাংশনে Redis-এর জন্য Upstash যোগ করার কোডটি দেখি। Webmentions সহায়ক ফাংশন অনুরূপ এবং আপনি GitHub রেপোতে এটি সম্পূর্ণ দেখতে পারেন (নীচের লিঙ্ক)।
import { Redis } from "upstash/mod.ts";
const UPSTASH_REDIS_REST_TOKEN = Deno.env.get("UPSTASH_REDIS_REST_TOKEN");
if (typeof UPSTASH_REDIS_REST_TOKEN === "undefined") {
console.error("env `UPSTASH_REDIS_REST_TOKEN` must be set");
}
const UPSTASH_REDIS_REST_URL = Deno.env.get("UPSTASH_REDIS_REST_URL");
if (typeof UPSTASH_REDIS_REST_URL === "undefined") {
console.error("env `UPSTASH_REDIS_REST_URL` must be set");
}
const redis = new Redis({
token: UPSTASH_REDIS_REST_TOKEN,
url: UPSTASH_REDIS_REST_URL,
});
প্রথমে, আমাদের Redis অবজেক্টের জন্য একটি Upstash আরম্ভ করতে হবে। আপনার UPSTASH_REDIS_REST_TOKEN প্রয়োজন এবং UPSTASH_REDIS_REST_URL Upstash কনসোল থেকে মান। আপনার যদি এখনও একটি না থাকে তবে একটি Upstash অ্যাকাউন্ট সেট আপ করা দ্রুত। উভয় মান যোগ করুন (UPSTASH_REDIS_REST_TOKEN এবং UPSTASH_REDIS_REST_URL ) একটি .env প্রজেক্ট রুট ডিরেক্টরিতে ফাইল।
প্রথম লাইনে লক্ষ্য করুন, উপরে, আমরা upstash ব্যবহার করি আমদানি মানচিত্র থেকে কী যা আমরা আগে সেট করেছি। প্রতিটি TypeScript ফাইলে সম্পূর্ণ আমদানি URL যোগ করার চেয়ে এটি আরও সুবিধাজনক। যখন upstash_redis এর পরবর্তী প্রকাশ উপলভ্য হলে আপনাকে শুধুমাত্র একটি জায়গায় সংস্করণ নম্বর আপডেট করতে হবে।
এখানে getTinybirdViews ফাংশন:
export async function getTinybirdViews({
days,
}: {
days: number;
}): Promise<number> {
try {
// ...TRUNCATED
const cachedCount = (await redis.get("view-count")) as number | null;
if (cachedCount != null) {
return cachedCount;
}
// ...TRUNCATED
const response = await fetch(
`https://api.tinybird.co/v0/pipes/${TINYBIRD_PIPE_NAME}.json?${params.toString()}`,
{
headers: {
Authorization: `Bearer ${TINYBIRD_TOKEN}`,
},
},
);
const {
data: [{ count_sessions: count = -1 }],
} = await response.json();
if (typeof count === "number" && count > 0) {
const CACHE_TTL_SECONDS = 14_400;
await redis.set("view-count", count);
await redis.expire("view-count", CACHE_TTL_SECONDS);
}
return count;
} catch (error: unknown) {
// ...TRUNCATED
}
} এখানে আমরা:
-
view-countএর জন্য Redis ক্যাশে করা মানগুলির জন্য ইতিমধ্যেই একটি Upstash আছে কিনা তা পরীক্ষা করুনredis.get('view-count')এ কল দিয়ে . - যদি একটি থাকে ক্যাশে করা মানটি ফেরত দিন, অন্যথায় টিনিবার্ড থেকে একটি নতুন মান পান৷
-
redis.set('view-count', value)কল করে Redis ক্যাশের জন্য Upstash-এ তাজা মান সংরক্ষণ করুন এবং একটি মেয়াদ শেষ করুন তারপরredis.expire(TTL). এটি বেঁচে থাকার সময় দিয়ে মান সেট করে (TTL ) মান যার পরে ডেটা বাসি বলে বিবেচিত হয়। আমরাTTLসেট করেছি এখানে চার ঘন্টা।getTinybirdViewsএ কল করার জন্য সেই সময়ের পরে, আমরা একটি নতুন মূল্যের জন্য টিনিবার্ডকে আঘাত করব।

Redis-এর জন্য Upstash-এর সাহায্যে পৃষ্ঠাটি (কয়েকবার) রিফ্রেশ করা উভয় ডেটা কোয়েরির মধ্যে একত্রিত করা হলে আমরা দেখতে পাই যে জিনিসগুলি দ্রুততর হচ্ছে। এখানে আমরা মাত্র 2 সেকেন্ড থেকে প্রায় 0.29 সেকেন্ডে নেমে এসেছি। এখানে সংখ্যায় খুব বেশি পড়বেন না কারণ আমরা স্থানীয়ভাবে চালাচ্ছি এবং আমাদের কাছে অনেক ডেটা পয়েন্ট নেই। আপনি কি ধরনের লাভ অর্জন করতে পারেন তা দেখতে আপনার নিজের অ্যাপে পরিষেবাটি ব্যবহার করে দেখুন৷
৷Redis এবং পারফরম্যান্স API-এর জন্য আপস্ট্যাশ:র্যাপিং আপ
এখানে, আমরা দেখেছি যে আপনি কীভাবে জাভাস্ক্রিপ্ট পারফরম্যান্স API ব্যবহার করতে পারেন আপনার অপ্টিমাইজেশন প্রচেষ্টা কোথায় ফোকাস করবেন সে বিষয়ে আপনার সিদ্ধান্তগুলিকে গাইড করতে সহায়তা করতে। এর বাইরে আমরা দেখেছি কিভাবে আপনি ডেনো ফ্রেশ-এ Redis-এর জন্য Upstash বাস্তবায়ন করতে পারেন। অবশেষে আমরা আবিষ্কার করেছি যে Deno ওয়েব APIs সার্ভার সাইড সমর্থন করে, শেখার বক্ররেখা সমতল করে। অপ্টিমাইজেশানের জন্য Deno-এর অন্য বড় সুবিধা হল তাত্ক্ষণিক স্থাপনা, আপনাকে একটি সংক্ষিপ্ত প্রতিক্রিয়া লুপ দেয় এবং সূক্ষ্ম-টিউনিং পারফরম্যান্সের সময় আপনাকে দ্রুত এগিয়ে যেতে দেয়।
আমি আশা করি আপনি Redis এর জন্য Upstash এবং পারফরম্যান্স API মূল্যবান সম্পর্কে পড়া খুঁজে পেয়েছেন। আপনি যদি Deno বা Deno Fresh-এ নতুন হয়ে থাকেন, Deno দিয়ে শুরু করার জন্য আমি তৈরি করেছি এমন কিছু বিষয়বস্তু দেখে নিন। আপনি GitHub-এ অ্যাপের জন্য সম্পূর্ণ কোড খুলতে পারেন।